97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import subprocess
|
|
import tempfile
|
|
import os
|
|
|
|
# Force temp files into a folder inside your project
|
|
custom_temp_dir = os.path.join(os.getcwd(), "tmp")
|
|
os.makedirs(custom_temp_dir, exist_ok=True)
|
|
tempfile.tempdir = custom_temp_dir
|
|
|
|
MVSHOST = "oldcomputernerd.com"
|
|
RDRPORT = 3505
|
|
MVS_PASSWORD = os.environ.get("MVS_BATCH_PASSWORD")
|
|
|
|
|
|
def create_delete_jcl(dataset_name, member_name):
|
|
"""Create JCL to delete a PDS member using IEHPROGM"""
|
|
|
|
jcl = f"""
|
|
//DELETE JOB (ACCT),'DELETE',
|
|
// USER=@05054,PASSWORD={MVS_PASSWORD},
|
|
// CLASS=A,MSGCLASS=H,NOTIFY=@05054
|
|
//DELMEM EXEC PGM=IEHPROGM
|
|
//SYSPRINT DD SYSOUT=*
|
|
//DD1 DD DSN={dataset_name},DISP=SHR
|
|
//SYSIN DD *
|
|
SCRATCH DSNAME={dataset_name},MEMBER={member_name}
|
|
/*
|
|
"""
|
|
return jcl
|
|
|
|
|
|
def delete_member(dataset_name, member_name, mvshost=MVSHOST):
|
|
"""Delete a member from MVS PDS"""
|
|
|
|
payload = create_delete_jcl(dataset_name, member_name)
|
|
|
|
# Write JCL to temporary file and submit via netcat
|
|
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.jcl') as tmpfile:
|
|
tmpfile.write(payload)
|
|
tmpfile.flush()
|
|
tmpfile_path = tmpfile.name
|
|
|
|
try:
|
|
with open(tmpfile_path, 'rb') as f:
|
|
result = subprocess.run(
|
|
['nc', '-w', '5', mvshost, str(RDRPORT)],
|
|
input=f.read(),
|
|
check=True,
|
|
capture_output=True
|
|
)
|
|
print(f"Deleted {dataset_name}({member_name})")
|
|
if result.stdout:
|
|
print("JES response:", result.stdout.decode(errors='ignore').strip())
|
|
return 0
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Deletion failed: {e}")
|
|
print("stderr:", e.stderr.decode(errors='ignore'))
|
|
return 1
|
|
finally:
|
|
os.unlink(tmpfile_path)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print("Usage: delete_mvs_member.py <pds_destination> [mvshost]")
|
|
print()
|
|
print("Arguments:")
|
|
print(" pds_destination - PDS destination as DATASET(MEMBER) (required)")
|
|
print(" mvshost - MVS host (optional, default: oldcomputernerd.com)")
|
|
print()
|
|
print("Examples:")
|
|
print(" delete_mvs_member.py '@05054.SRCLIB.C(SIEVE11)'")
|
|
print(" delete_mvs_member.py '@05054.SRCLIB.C(HELLO)' mainframe.example.com")
|
|
sys.exit(1)
|
|
|
|
destination = sys.argv[1]
|
|
|
|
# Parse PDS syntax: DATASET(MEMBER)
|
|
if '(' in destination and destination.endswith(')'):
|
|
dataset_name = destination[:destination.index('(')]
|
|
member_name = destination[destination.index('(')+1:-1]
|
|
else:
|
|
print(f"Error: Invalid PDS syntax '{destination}'. Use format: DATASET(MEMBER)")
|
|
sys.exit(1)
|
|
|
|
# Optional host override
|
|
mvshost = sys.argv[2] if len(sys.argv) > 2 else MVSHOST
|
|
|
|
print(f"Deleting: {dataset_name}({member_name})")
|
|
print(f"Host: {mvshost}")
|
|
print()
|
|
|
|
sys.exit(delete_member(dataset_name, member_name, mvshost))
|