rda-python-miscs 2.0.15__tar.gz → 3.0.0__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_miscs-3.0.0/PKG-INFO +156 -0
- rda_python_miscs-3.0.0/README.md +139 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/pyproject.toml +11 -5
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/bashqsub.py +60 -5
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/bashqsub.usg +7 -7
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/gdexls.py +99 -8
- rda_python_miscs-3.0.0/src/rda_python_miscs/gdexls.usg +74 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/pg_rst.py +5 -0
- rda_python_miscs-3.0.0/src/rda_python_miscs/pg_rst.usg +60 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/pg_wget.py +21 -8
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/pgwget.py +41 -24
- rda_python_miscs-3.0.0/src/rda_python_miscs/pgwget.usg +75 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdacp.py +61 -6
- rda_python_miscs-3.0.0/src/rda_python_miscs/rdacp.usg +77 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdakill.py +93 -12
- rda_python_miscs-3.0.0/src/rda_python_miscs/rdakill.usg +66 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdamod.py +63 -10
- rda_python_miscs-3.0.0/src/rda_python_miscs/rdamod.usg +71 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdaown.py +55 -6
- rda_python_miscs-3.0.0/src/rda_python_miscs/rdaown.usg +60 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdaps.py +37 -5
- rda_python_miscs-3.0.0/src/rda_python_miscs/rdaps.usg +55 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdasub.py +45 -8
- rda_python_miscs-3.0.0/src/rda_python_miscs/rdasub.usg +49 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdazip.py +20 -4
- rda_python_miscs-3.0.0/src/rda_python_miscs/rdazip.usg +56 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/tcshqsub.py +58 -3
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/tcshqsub.usg +9 -9
- rda_python_miscs-3.0.0/src/rda_python_miscs.egg-info/PKG-INFO +156 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs.egg-info/SOURCES.txt +2 -0
- rda_python_miscs-3.0.0/src/rda_python_miscs.egg-info/entry_points.txt +20 -0
- rda_python_miscs-2.0.15/PKG-INFO +0 -18
- rda_python_miscs-2.0.15/README.md +0 -1
- rda_python_miscs-2.0.15/src/rda_python_miscs/gdexls.usg +0 -60
- rda_python_miscs-2.0.15/src/rda_python_miscs/rdacp.usg +0 -62
- rda_python_miscs-2.0.15/src/rda_python_miscs/rdakill.usg +0 -36
- rda_python_miscs-2.0.15/src/rda_python_miscs/rdamod.usg +0 -51
- rda_python_miscs-2.0.15/src/rda_python_miscs/rdaown.usg +0 -46
- rda_python_miscs-2.0.15/src/rda_python_miscs/rdaps.usg +0 -29
- rda_python_miscs-2.0.15/src/rda_python_miscs/rdasub.usg +0 -12
- rda_python_miscs-2.0.15/src/rda_python_miscs/rdazip.usg +0 -20
- rda_python_miscs-2.0.15/src/rda_python_miscs.egg-info/PKG-INFO +0 -18
- rda_python_miscs-2.0.15/src/rda_python_miscs.egg-info/entry_points.txt +0 -14
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/LICENSE +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/MANIFEST.in +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/setup.cfg +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/__init__.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/bash_qsub.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/gdex_ls.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/gdexls_standalone.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/pg_docs.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rda_cp.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rda_kill.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rda_mod.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rda_own.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rda_ps.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rda_sub.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rda_zip.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdals.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rdals.usg +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rst_templates/index.rst.temp +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/rst_templates/section.rst.temp +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs/tcsh_qsub.py +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs.egg-info/dependency_links.txt +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs.egg-info/requires.txt +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/src/rda_python_miscs.egg-info/top_level.txt +0 -0
- {rda_python_miscs-2.0.15 → rda_python_miscs-3.0.0}/tests/test_miscs.py +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rda_python_miscs
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: RDA Python package to hold RDA miscellaneous utility programs
|
|
5
|
+
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
|
+
Project-URL: Homepage, https://github.com/NCAR/rda-python-miscs
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Requires-Python: >=3.7
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: rda_python_common
|
|
15
|
+
Requires-Dist: rda_python_setuid
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# rda_python_miscs
|
|
19
|
+
|
|
20
|
+
RDA Python package to hold miscellaneous utility programs for the
|
|
21
|
+
[NSF NCAR Geoscience Data Exchange (GDEX)](https://gdex.ucar.edu).
|
|
22
|
+
|
|
23
|
+
## Programs
|
|
24
|
+
|
|
25
|
+
The package provides two categories of programs:
|
|
26
|
+
|
|
27
|
+
**Run as current user (no setuid required):**
|
|
28
|
+
|
|
29
|
+
| Command | Alias | Description |
|
|
30
|
+
|---------|-------|-------------|
|
|
31
|
+
| `bashqsub` | | Submit a job as a bash batch job on a PBS node via qsub |
|
|
32
|
+
| `tcshqsub` | | Submit a job as a tcsh batch job on a PBS node via qsub |
|
|
33
|
+
| `rdasub` | `gdexsub` | Submit a command as a nohup background process on the local machine |
|
|
34
|
+
| `pgwget` | | Download remote files by root name pattern, combining downloaded parts into a single file |
|
|
35
|
+
| `gdexls` | | List local files and directories with matching metadata from the GDEX database |
|
|
36
|
+
| `rdaps` | `gdexps` | Show process status for local or PBS batch processes, with filtering by PID, owner, or name |
|
|
37
|
+
| `rdazip` | `gdexzip` | Compress or uncompress files using a supported format |
|
|
38
|
+
| `rdaown` | `gdexown` | Change ownership of files and directories to rdadata (must be run as root) |
|
|
39
|
+
| `pgrst` | | Convert .usg files to RST and push to gdex-docs-* repos on GitHub for readthedocs.io |
|
|
40
|
+
|
|
41
|
+
**Run as gdexdata via setuid (requires setup below):**
|
|
42
|
+
|
|
43
|
+
| Command | Alias | Connector script | Description |
|
|
44
|
+
|---------|-------|-----------------|-------------|
|
|
45
|
+
| `rdacp` | `gdexcp` | `setuid_rdacp` / `setuid_gdexcp` | Copy files and directories across local, remote, Object Store, or Globus endpoints |
|
|
46
|
+
| `rdakill` | `gdexkill` | `setuid_rdakill` / `setuid_gdexkill` | Kill local processes and their children, or cancel PBS batch jobs |
|
|
47
|
+
| `rdamod` | `gdexmod` | `setuid_rdamod` / `setuid_gdexmod` | Change permission modes for files and directories owned by rdadata |
|
|
48
|
+
|
|
49
|
+
## Environment setup
|
|
50
|
+
|
|
51
|
+
Create a Python environment first; package installs in the next section run
|
|
52
|
+
inside whichever environment you activate here.
|
|
53
|
+
|
|
54
|
+
### Option A — Python venv (DECS machines)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
python3 -m venv $ENVHOME # e.g. /glade/u/home/gdexdata/gdexmsenv
|
|
58
|
+
source $ENVHOME/bin/activate
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Option B — Conda (DAV/Casper)
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
conda create --prefix $ENVHOME python=3.12 # e.g. /glade/work/gdexdata/conda-envs/pg-gdex
|
|
65
|
+
conda activate $ENVHOME
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Installing rda-python-miscs
|
|
69
|
+
|
|
70
|
+
Pick whichever install mode fits your workflow. All four pull in the
|
|
71
|
+
transitive dependencies (`rda_python_common`, `rda_python_setuid`)
|
|
72
|
+
automatically.
|
|
73
|
+
|
|
74
|
+
For local development, clone this repo alongside your project and install it
|
|
75
|
+
in editable mode so that changes are picked up without re-installing:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git clone https://github.com/NCAR/rda-python-miscs.git
|
|
79
|
+
cd rda-python-miscs
|
|
80
|
+
pip install -e .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
To test a specific branch (e.g. an in-progress feature or fix branch), pass
|
|
84
|
+
`-b/--branch` to `git clone`:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
git clone -b <branch-name> https://github.com/NCAR/rda-python-miscs.git
|
|
88
|
+
cd rda-python-miscs
|
|
89
|
+
pip install -e .
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
For a regular (non-editable) install from a checkout:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install /path/to/rda-python-miscs
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
For a production install on a system that uses the published distribution:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
pip install rda_python_miscs
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Setuid Setup
|
|
105
|
+
|
|
106
|
+
The setuid programs (`rdacp`, `rdakill`, `rdamod` and their `gdex*` aliases)
|
|
107
|
+
execute as the common user `PGLOG['COMMONUSER']` (default `gdexdata`) via
|
|
108
|
+
the `rda_python_setuid` mechanism, which is pulled in automatically as a
|
|
109
|
+
dependency. After `pip install` above, choose one of the wiring options
|
|
110
|
+
below.
|
|
111
|
+
|
|
112
|
+
### Full setuid install (requires sudo access to COMMONUSER)
|
|
113
|
+
|
|
114
|
+
Run these steps once per environment:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# 1. Compile the pywrapper C binary (once per environment):
|
|
118
|
+
pywrapper-install -c|--compile -n|--username gdexdata
|
|
119
|
+
|
|
120
|
+
# 2. Wire up all setuid programs in one pass:
|
|
121
|
+
pywrapper-install -l|--link all
|
|
122
|
+
|
|
123
|
+
# 3. Optionally, install a pgstart_<loginname> binary so <loginname> (any
|
|
124
|
+
# user in the same group as PGLOG['COMMONUSER']) can run commands as
|
|
125
|
+
# themselves. Run either by PGLOG['ADMINUSER'] (default zji, if it has
|
|
126
|
+
# 'sudo -u <loginname>'), or by <loginname> directly:
|
|
127
|
+
pywrapper-install -p|--pgstart -n|--username <loginname>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`pywrapper-install` with no arguments displays the full user guide.
|
|
131
|
+
|
|
132
|
+
### Simple install (no sudo required, runs as current user)
|
|
133
|
+
|
|
134
|
+
Users who do not need the setuid mechanism can create direct symlinks instead:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pywrapper-install -l|--link all -s|--simple
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
This creates `bin/<name> -> bin/setuid_<name>` for every setuid program and
|
|
141
|
+
they run as the current user with no privilege change.
|
|
142
|
+
|
|
143
|
+
### Update an existing installation (no sudo required)
|
|
144
|
+
|
|
145
|
+
When the package is upgraded and a new `pywrapper.c` is bundled, recompile and
|
|
146
|
+
reinstall all setuid binaries using the existing `pgstart_*` binaries:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
pywrapper-install -u|--update
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Setup guide
|
|
153
|
+
|
|
154
|
+
The shared setuid setup guide is shown automatically if any `setuid_*`
|
|
155
|
+
connector script is invoked directly before the setuid wrapper has been
|
|
156
|
+
configured.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# rda_python_miscs
|
|
2
|
+
|
|
3
|
+
RDA Python package to hold miscellaneous utility programs for the
|
|
4
|
+
[NSF NCAR Geoscience Data Exchange (GDEX)](https://gdex.ucar.edu).
|
|
5
|
+
|
|
6
|
+
## Programs
|
|
7
|
+
|
|
8
|
+
The package provides two categories of programs:
|
|
9
|
+
|
|
10
|
+
**Run as current user (no setuid required):**
|
|
11
|
+
|
|
12
|
+
| Command | Alias | Description |
|
|
13
|
+
|---------|-------|-------------|
|
|
14
|
+
| `bashqsub` | | Submit a job as a bash batch job on a PBS node via qsub |
|
|
15
|
+
| `tcshqsub` | | Submit a job as a tcsh batch job on a PBS node via qsub |
|
|
16
|
+
| `rdasub` | `gdexsub` | Submit a command as a nohup background process on the local machine |
|
|
17
|
+
| `pgwget` | | Download remote files by root name pattern, combining downloaded parts into a single file |
|
|
18
|
+
| `gdexls` | | List local files and directories with matching metadata from the GDEX database |
|
|
19
|
+
| `rdaps` | `gdexps` | Show process status for local or PBS batch processes, with filtering by PID, owner, or name |
|
|
20
|
+
| `rdazip` | `gdexzip` | Compress or uncompress files using a supported format |
|
|
21
|
+
| `rdaown` | `gdexown` | Change ownership of files and directories to rdadata (must be run as root) |
|
|
22
|
+
| `pgrst` | | Convert .usg files to RST and push to gdex-docs-* repos on GitHub for readthedocs.io |
|
|
23
|
+
|
|
24
|
+
**Run as gdexdata via setuid (requires setup below):**
|
|
25
|
+
|
|
26
|
+
| Command | Alias | Connector script | Description |
|
|
27
|
+
|---------|-------|-----------------|-------------|
|
|
28
|
+
| `rdacp` | `gdexcp` | `setuid_rdacp` / `setuid_gdexcp` | Copy files and directories across local, remote, Object Store, or Globus endpoints |
|
|
29
|
+
| `rdakill` | `gdexkill` | `setuid_rdakill` / `setuid_gdexkill` | Kill local processes and their children, or cancel PBS batch jobs |
|
|
30
|
+
| `rdamod` | `gdexmod` | `setuid_rdamod` / `setuid_gdexmod` | Change permission modes for files and directories owned by rdadata |
|
|
31
|
+
|
|
32
|
+
## Environment setup
|
|
33
|
+
|
|
34
|
+
Create a Python environment first; package installs in the next section run
|
|
35
|
+
inside whichever environment you activate here.
|
|
36
|
+
|
|
37
|
+
### Option A — Python venv (DECS machines)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
python3 -m venv $ENVHOME # e.g. /glade/u/home/gdexdata/gdexmsenv
|
|
41
|
+
source $ENVHOME/bin/activate
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Option B — Conda (DAV/Casper)
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
conda create --prefix $ENVHOME python=3.12 # e.g. /glade/work/gdexdata/conda-envs/pg-gdex
|
|
48
|
+
conda activate $ENVHOME
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Installing rda-python-miscs
|
|
52
|
+
|
|
53
|
+
Pick whichever install mode fits your workflow. All four pull in the
|
|
54
|
+
transitive dependencies (`rda_python_common`, `rda_python_setuid`)
|
|
55
|
+
automatically.
|
|
56
|
+
|
|
57
|
+
For local development, clone this repo alongside your project and install it
|
|
58
|
+
in editable mode so that changes are picked up without re-installing:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/NCAR/rda-python-miscs.git
|
|
62
|
+
cd rda-python-miscs
|
|
63
|
+
pip install -e .
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
To test a specific branch (e.g. an in-progress feature or fix branch), pass
|
|
67
|
+
`-b/--branch` to `git clone`:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone -b <branch-name> https://github.com/NCAR/rda-python-miscs.git
|
|
71
|
+
cd rda-python-miscs
|
|
72
|
+
pip install -e .
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For a regular (non-editable) install from a checkout:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install /path/to/rda-python-miscs
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For a production install on a system that uses the published distribution:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install rda_python_miscs
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Setuid Setup
|
|
88
|
+
|
|
89
|
+
The setuid programs (`rdacp`, `rdakill`, `rdamod` and their `gdex*` aliases)
|
|
90
|
+
execute as the common user `PGLOG['COMMONUSER']` (default `gdexdata`) via
|
|
91
|
+
the `rda_python_setuid` mechanism, which is pulled in automatically as a
|
|
92
|
+
dependency. After `pip install` above, choose one of the wiring options
|
|
93
|
+
below.
|
|
94
|
+
|
|
95
|
+
### Full setuid install (requires sudo access to COMMONUSER)
|
|
96
|
+
|
|
97
|
+
Run these steps once per environment:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 1. Compile the pywrapper C binary (once per environment):
|
|
101
|
+
pywrapper-install -c|--compile -n|--username gdexdata
|
|
102
|
+
|
|
103
|
+
# 2. Wire up all setuid programs in one pass:
|
|
104
|
+
pywrapper-install -l|--link all
|
|
105
|
+
|
|
106
|
+
# 3. Optionally, install a pgstart_<loginname> binary so <loginname> (any
|
|
107
|
+
# user in the same group as PGLOG['COMMONUSER']) can run commands as
|
|
108
|
+
# themselves. Run either by PGLOG['ADMINUSER'] (default zji, if it has
|
|
109
|
+
# 'sudo -u <loginname>'), or by <loginname> directly:
|
|
110
|
+
pywrapper-install -p|--pgstart -n|--username <loginname>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`pywrapper-install` with no arguments displays the full user guide.
|
|
114
|
+
|
|
115
|
+
### Simple install (no sudo required, runs as current user)
|
|
116
|
+
|
|
117
|
+
Users who do not need the setuid mechanism can create direct symlinks instead:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
pywrapper-install -l|--link all -s|--simple
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
This creates `bin/<name> -> bin/setuid_<name>` for every setuid program and
|
|
124
|
+
they run as the current user with no privilege change.
|
|
125
|
+
|
|
126
|
+
### Update an existing installation (no sudo required)
|
|
127
|
+
|
|
128
|
+
When the package is upgraded and a new `pywrapper.c` is bundled, recompile and
|
|
129
|
+
reinstall all setuid binaries using the existing `pgstart_*` binaries:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
pywrapper-install -u|--update
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Setup guide
|
|
136
|
+
|
|
137
|
+
The shared setuid setup guide is shown automatically if any `setuid_*`
|
|
138
|
+
connector script is invoked directly before the setuid wrapper has been
|
|
139
|
+
configured.
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "rda_python_miscs"
|
|
9
|
-
version = "
|
|
9
|
+
version = "3.0.0"
|
|
10
10
|
authors = [
|
|
11
11
|
{ name="Zaihua Ji", email="zji@ucar.edu" },
|
|
12
12
|
]
|
|
@@ -36,13 +36,19 @@ pythonpath = [
|
|
|
36
36
|
"bashqsub" = "rda_python_miscs.bashqsub:main"
|
|
37
37
|
"tcshqsub" = "rda_python_miscs.tcshqsub:main"
|
|
38
38
|
"rdasub" = "rda_python_miscs.rdasub:main"
|
|
39
|
+
"gdexsub" = "rda_python_miscs.rdasub:main"
|
|
39
40
|
"pgwget" = "rda_python_miscs.pgwget:main"
|
|
40
|
-
"rdals" = "rda_python_miscs.rdals:main"
|
|
41
41
|
"gdexls" = "rda_python_miscs.gdexls:main"
|
|
42
42
|
"rdaps" = "rda_python_miscs.rdaps:main"
|
|
43
|
+
"gdexps" = "rda_python_miscs.rdaps:main"
|
|
43
44
|
"rdazip" = "rda_python_miscs.rdazip:main"
|
|
45
|
+
"gdexzip" = "rda_python_miscs.rdazip:main"
|
|
44
46
|
"rdaown" = "rda_python_miscs.rdaown:main"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
47
|
+
"gdexown" = "rda_python_miscs.rdaown:main"
|
|
48
|
+
"setuid_rdacp" = "rda_python_miscs.rdacp:main"
|
|
49
|
+
"setuid_gdexcp" = "rda_python_miscs.rdacp:main"
|
|
50
|
+
"setuid_rdakill" = "rda_python_miscs.rdakill:main"
|
|
51
|
+
"setuid_gdexkill" = "rda_python_miscs.rdakill:main"
|
|
52
|
+
"setuid_rdamod" = "rda_python_miscs.rdamod:main"
|
|
53
|
+
"setuid_gdexmod" = "rda_python_miscs.rdamod:main"
|
|
48
54
|
"pgrst" = "rda_python_miscs.pg_rst:main"
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# https://github.com/NCAR/rda-utility-programs.git
|
|
8
8
|
# 2025-12-29 convert to class BashQsub
|
|
9
9
|
# Purpose: python script to submit a batch job on PBS node via bash script
|
|
10
|
-
# Github: https://github.com/NCAR/rda-
|
|
10
|
+
# Github: https://github.com/NCAR/rda-python-miscs.git
|
|
11
11
|
##################################################################################
|
|
12
12
|
import os
|
|
13
13
|
import sys
|
|
@@ -16,8 +16,14 @@ from os import path as op
|
|
|
16
16
|
from rda_python_common.pg_log import PgLOG
|
|
17
17
|
|
|
18
18
|
class BashQsub(PgLOG):
|
|
19
|
+
"""Submit a PBS batch job via a dynamically generated bash script using qsub.
|
|
20
|
+
|
|
21
|
+
Builds a bash script with PBS directives, module loads, and conda environment
|
|
22
|
+
activation, then submits it through the PBS qsub command.
|
|
23
|
+
"""
|
|
19
24
|
|
|
20
25
|
def __init__(self):
|
|
26
|
+
"""Initialize BashQsub with default PBS resource settings and options."""
|
|
21
27
|
super().__init__()
|
|
22
28
|
self.DEFMODS = {
|
|
23
29
|
'default': "ncarenv,netcdf,ncl,nco,cdo,conda,grib-util,wgrib2"
|
|
@@ -42,8 +48,15 @@ class BashQsub(PgLOG):
|
|
|
42
48
|
self.gdexsub = self.BCHCMDS['PBS']
|
|
43
49
|
self.args = None
|
|
44
50
|
|
|
45
|
-
# function to
|
|
51
|
+
# function to read parameters
|
|
46
52
|
def read_parameters(self):
|
|
53
|
+
"""Parse command-line arguments and populate PBS options and customized options.
|
|
54
|
+
|
|
55
|
+
Handles single-dash qsub options (e.g. -q, -A, -l) and long custom options
|
|
56
|
+
(-cmd, -cwd, -env, -mod, -res). Validates that the qsub command is available
|
|
57
|
+
and that a -cmd value is provided. Sets default log paths and job name if not
|
|
58
|
+
specified, and changes the working directory if -cwd is given.
|
|
59
|
+
"""
|
|
47
60
|
aname = 'bashqsub'
|
|
48
61
|
pname = 'gdexqsub'
|
|
49
62
|
self.set_help_path(__file__)
|
|
@@ -88,11 +101,12 @@ class BashQsub(PgLOG):
|
|
|
88
101
|
if not self.SOPTIONS['e']: self.SOPTIONS['e'] = "{}/{}/".format(self.PGLOG['LOGPATH'], pname)
|
|
89
102
|
if 'N' not in self.SOPTIONS: self.SOPTIONS['N'] = op.basename(self.coptions['cmd'])
|
|
90
103
|
if self.coptions['cwd']:
|
|
91
|
-
if '
|
|
104
|
+
if '$' in self.coptions['cwd']: self.coptions['cwd'] = self.replace_environments(self.coptions['cwd'], '', self.LGWNEX)
|
|
92
105
|
os.chdir(self.coptions['cwd'])
|
|
93
106
|
|
|
94
107
|
# function to start actions
|
|
95
108
|
def start_actions(self):
|
|
109
|
+
"""Resolve the command path, build the bash script, and submit it via qsub."""
|
|
96
110
|
cmd = self.valid_command(self.coptions['cmd'])
|
|
97
111
|
if not cmd and not re.match(r'^/', self.coptions['cmd']): cmd = self.valid_command('./' + self.coptions['cmd'])
|
|
98
112
|
if not cmd: self.pglog(self.coptions['cmd'] + ": Cannot find given command to run", self.LGWNEX)
|
|
@@ -105,6 +119,17 @@ class BashQsub(PgLOG):
|
|
|
105
119
|
|
|
106
120
|
# build bash script to submit a PBS batch job
|
|
107
121
|
def build_bash_script(self, cmd):
|
|
122
|
+
"""Build and return a bash script string with PBS directives for the given command.
|
|
123
|
+
|
|
124
|
+
Sets HOME, sources system and conda profile scripts and the user's .bashrc,
|
|
125
|
+
loads modules, activates the conda environment, then runs the command.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
cmd (str): The fully-resolved command (with arguments) to execute in the job.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
str: The complete bash batch script content.
|
|
132
|
+
"""
|
|
108
133
|
buf = "#!/usr/bin/bash\n\n" # qsub starting bash script
|
|
109
134
|
if 'l' in self.SOPTIONS: self.add_resources()
|
|
110
135
|
# add options to bash script for qsub
|
|
@@ -128,8 +153,13 @@ class BashQsub(PgLOG):
|
|
|
128
153
|
buf += "\necho {}\n{}\n\ndate\n".format(cmd, cmd)
|
|
129
154
|
return buf
|
|
130
155
|
|
|
131
|
-
# check and add resource options
|
|
156
|
+
# check and add resource options
|
|
132
157
|
def add_resources(self):
|
|
158
|
+
"""Parse -l option value into the RESOURCES dict and remove the raw -l entry.
|
|
159
|
+
|
|
160
|
+
Expects comma-separated name=value pairs (e.g. 'walltime=2:00:00,select=1:ncpus=4').
|
|
161
|
+
Logs an error if a token does not contain '='.
|
|
162
|
+
"""
|
|
133
163
|
for res in re.split(',', self.SOPTIONS['l']):
|
|
134
164
|
ms = re.match(r'^([^=]+)=(.+)$', res)
|
|
135
165
|
if ms:
|
|
@@ -140,6 +170,20 @@ class BashQsub(PgLOG):
|
|
|
140
170
|
|
|
141
171
|
# add module loads for modules provided
|
|
142
172
|
def add_modules(self, res, mods):
|
|
173
|
+
"""Build and return module load/unload commands for the bash script.
|
|
174
|
+
|
|
175
|
+
Loads the default module set for the given reservation (or the 'default' set).
|
|
176
|
+
Additional modules in ``mods`` are appended; path-style entries (starting with
|
|
177
|
+
'/') use 'module use' instead of 'module load'. Modules already in the default
|
|
178
|
+
set are skipped. SWAPMODS entries trigger an unload before the new load.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
res (str): Reservation name used to look up DEFMODS; falls back to 'default'.
|
|
182
|
+
mods (str): Comma-separated list of extra modules (or None).
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
str: Shell commands to load/unload modules.
|
|
186
|
+
"""
|
|
143
187
|
mbuf = "\n"
|
|
144
188
|
defmods = self.DEFMODS[res] if res in self.DEFMODS else self.DEFMODS['default']
|
|
145
189
|
dmods = re.split(',', defmods)
|
|
@@ -163,6 +207,16 @@ class BashQsub(PgLOG):
|
|
|
163
207
|
|
|
164
208
|
# set virtual machine libraries
|
|
165
209
|
def set_vm_libs(self, res):
|
|
210
|
+
"""Build and return conda/VM library activation commands for the bash script.
|
|
211
|
+
|
|
212
|
+
Looks up DEFLIBS for the given reservation (falls back to 'default').
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
res (str): Reservation name used to look up DEFLIBS; falls back to 'default'.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
str: Shell commands to activate virtual environment libraries, or '' if none.
|
|
219
|
+
"""
|
|
166
220
|
deflibs = self.DEFLIBS[res] if res in self.DEFLIBS else self.DEFLIBS['default']
|
|
167
221
|
if not deflibs: return ''
|
|
168
222
|
dlibs = re.split(',', deflibs)
|
|
@@ -171,8 +225,9 @@ class BashQsub(PgLOG):
|
|
|
171
225
|
libbuf += dlib + "\n"
|
|
172
226
|
return libbuf
|
|
173
227
|
|
|
174
|
-
# main function to
|
|
228
|
+
# main function to execute this script
|
|
175
229
|
def main():
|
|
230
|
+
"""Entry point: instantiate BashQsub, parse arguments, run, and exit."""
|
|
176
231
|
object = BashQsub()
|
|
177
232
|
object.read_parameters()
|
|
178
233
|
object.start_actions()
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
-o LOGPATH/gdexqsub/
|
|
11
11
|
-e LOGPATH/gdexqsub/
|
|
12
12
|
-A P43713000
|
|
13
|
-
-m
|
|
14
|
-
-q gdex
|
|
15
|
-
-l walltime=6:00:00,select=1:
|
|
13
|
+
-m n
|
|
14
|
+
-q gdex@casper-pbs
|
|
15
|
+
-l walltime=6:00:00,select=1:ncpus=1:mem=1gb
|
|
16
16
|
|
|
17
17
|
- Option -cwd, set the working directory for the Command to be executed. If
|
|
18
18
|
it is not specified, it defaults to the current directory where qsub
|
|
@@ -33,18 +33,18 @@
|
|
|
33
33
|
A bash script example:
|
|
34
34
|
#!/usr/bin/bash
|
|
35
35
|
|
|
36
|
-
#PBS -o /
|
|
37
|
-
#PBS -e /
|
|
36
|
+
#PBS -o /glade/u/home/gdexdata/dssdb/log/gdexqsub/
|
|
37
|
+
#PBS -e /glade/u/home/gdexdata/dssdb/log/gdexqsub/
|
|
38
38
|
#PBS -A P43713000
|
|
39
39
|
#PBS -q gdex@casper-pbs
|
|
40
40
|
#PBS -m n
|
|
41
41
|
#PBS -N dsrqst
|
|
42
42
|
#PBS -l walltime=1:00:00
|
|
43
43
|
#PBS -l select=1:ncpus=1:mem=1gb
|
|
44
|
-
export HOME=/
|
|
44
|
+
export HOME=/glade/u/home/zji
|
|
45
45
|
source /etc/profile.d/z00_modules.sh
|
|
46
46
|
source /glade/u/apps/opt/conda/etc/profile.d/conda.sh
|
|
47
|
-
source /
|
|
47
|
+
source /glade/u/home/zji/.bashrc
|
|
48
48
|
pwd; hostname; date
|
|
49
49
|
|
|
50
50
|
module load ncarenv
|