#!/usr/bin/env python3 import sys import subprocess import tempfile import os # Force temp files into a folder inside your project (fully owned by you) custom_temp_dir = os.path.join(os.getcwd(), "tmp") os.makedirs(custom_temp_dir, exist_ok=True) tempfile.tempdir = custom_temp_dir SRCLIB = "src" JCLLIB = "jcl" MVSHOST = "oldcomputernerd.com" RDRPORT = 3505 MVS_PASSWORD = os.environ.get("MVS_BATCH_PASSWORD") def create_jcl_payload(local_file, dataset_name, member_name): with open(local_file, 'r') as f: sysin = f.readlines() # PDS member: Use IEBUPDTE jcl = f""" //UPLOAD JOB (ACCT),'UPLOAD', // USER=@05054,PASSWORD={MVS_PASSWORD}, // CLASS=A,MSGCLASS=H,NOTIFY=@05054 //COPY EXEC PGM=IEBUPDTE,PARM=NEW //SYSPRINT DD SYSOUT=* //SYSUT1 DD DUMMY //SYSUT2 DD DSN={dataset_name},DISP=MOD,UNIT=SYSDA, // DCB=(RECFM=FB,LRECL=80,BLKSIZE=0) //SYSIN DD * """ # Append control statement, source lines, end, and terminator (no leading space on ./) jcl += f"./ ADD NAME={member_name}\n" for line in sysin: line = line.rstrip('\n')[:80] jcl += line.ljust(80) + "\n" jcl += "./ ENDUP\n" jcl += "/*\n" return jcl def upload_source(local_file, dataset_name, member_name, mvshost=MVSHOST): """Upload source code to MVS PDS member""" # Read the source file # full path will come from the job runner # filepath = os.path.join(SRCLIB, local_file) payload = create_jcl_payload(local_file, 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: subprocess.run( ['nc', '-w', '5', mvshost, str(RDRPORT)], input=f.read(), check=True, capture_output=True ) print(f"Uploaded {local_file} to {dataset_name}({member_name})") return 0 except subprocess.CalledProcessError as e: print(f"Upload failed: {e}") print("stderr:", e.stderr.decode(errors='ignore')) return 1 finally: # Clean up outside os.unlink(tmpfile_path) def submit_jcl(job, mvshost="oldcomputernerd.com"): """Submit JCL job from local directory""" subjcl = os.path.join(JCLLIB, f"{job}.jcl") if not os.path.exists(subjcl): print(f"JCL file {subjcl} not found") return 1 subcmd = f"nc -w 5 {mvshost} {RDRPORT} < {subjcl}" try: subprocess.run(subcmd, shell=True, check=True) print(f"Submitted JCL job: {job}") return 0 except subprocess.CalledProcessError as e: print(f"JCL submission failed: {e}") return 1 if __name__ == "__main__": if len(sys.argv) < 5: print("Usage: mvs_job.py [mvshost]") sys.exit(1) local_file = sys.argv[1] dataset_name = sys.argv[2] member_name = sys.argv[3] job = sys.argv[4] mvshost = sys.argv[5] if len(sys.argv) > 5 else MVSHOST # Step 1: Upload source to PDS if upload_source(local_file, dataset_name, member_name, mvshost) != 0: sys.exit(1) # Step 2: Submit JCL job submit_jcl(job, mvshost)