""" GBS Application Build & Push Script (Python version) Run from local Windows machine - handles SFTP upload + remote build + push. Usage: python build_push.py [version-suffix] Example: python build_push.py E:\\projects\\xxx\\target\\app.jar jjb-saas-safety-eval ota 1 Result image: jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1 """ import paramiko import sys import os import time from datetime import datetime # ---- Configuration ---- MASTER = "192.168.20.100" SSH_USER = "root" SSH_PASSWD = "Zcloud@zcloud100" ACR_REGISTRY = "jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com" ACR_NAMESPACE = "ali_img_ns" ACR_USER = "10952138@qq.com" ACR_PASS = "idurCT!rIq9EzISD" SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) DOCKERFILE_PATH = os.path.join(SCRIPT_DIR, "Dockerfile") def ssh_exec(client, cmd, timeout=600): """Execute SSH command and print results.""" print(f" > {cmd[:120]}{'...' if len(cmd) > 120 else ''}") stdin, stdout, stderr = client.exec_command(cmd, timeout=timeout) out = stdout.read().decode('utf-8', errors='replace') err = stderr.read().decode('utf-8', errors='replace') exit_code = stdout.channel.recv_exit_status() if out.strip(): for line in out.strip().split('\n')[-10:]: # last 10 lines print(f" {line}") if err.strip(): important = [l for l in err.strip().split('\n') if not any(x in l for x in ['Downloading', 'Downloaded', 'Extracting', 'Progress'])] if important: print(f" [stderr] {'; '.join(important[:5])}") return out.strip(), err.strip(), exit_code def main(): if len(sys.argv) < 4: print(__doc__) sys.exit(1) jar_local = sys.argv[1] app_name = sys.argv[2] env_prefix = sys.argv[3] version_suffix = sys.argv[4] if len(sys.argv) > 4 else "1" date_tag = datetime.now().strftime("%Y%m%d") image_tag = f"{env_prefix}-{date_tag}-{version_suffix}" full_image = f"{ACR_REGISTRY}/{ACR_NAMESPACE}/prod-aly-{env_prefix}-dragon-{app_name}:{image_tag}" if not os.path.exists(jar_local): print(f"ERROR: JAR file not found: {jar_local}") sys.exit(1) jar_size_mb = os.path.getsize(jar_local) / 1024 / 1024 build_dir = f"/tmp/docker-build-{app_name}" jar_name = os.path.basename(jar_local) print("=" * 60) print(f" GBS Docker Build & Push (Remote)") print("=" * 60) print(f" JAR: {jar_local} ({jar_size_mb:.1f} MB)") print(f" App: {app_name}") print(f" Tag: {image_tag}") print(f" Image: {full_image}") print(f" Target: {MASTER}") print("=" * 60) # ---- Connect ---- client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(MASTER, username=SSH_USER, password=SSH_PASSWD, timeout=30) print("\n[1/5] SSH connected") # ---- Prepare remote dir ---- ssh_exec(client, f"rm -rf {build_dir} && mkdir -p {build_dir}/target") # ---- Upload JAR ---- print(f"\n[2/5] Uploading JAR ({jar_size_mb:.1f} MB)...") sftp = client.open_sftp() remote_jar = f"{build_dir}/target/{jar_name}" start = time.time() last_pct = -1 def progress(transferred, total): nonlocal last_pct pct = int(transferred * 100 / total) if pct >= last_pct + 10: last_pct = pct mb = transferred / 1024 / 1024 elapsed = time.time() - start speed = mb / elapsed if elapsed > 0 else 0 print(f" {pct}% ({mb:.1f} MB) - {speed:.1f} MB/s") sftp.put(jar_local, remote_jar, callback=progress) elapsed = time.time() - start print(f" Done in {elapsed:.1f}s ({jar_size_mb/elapsed:.1f} MB/s)") sftp.close() # ---- Upload Dockerfile ---- ssh_exec(client, f"cat > {build_dir}/Dockerfile", timeout=10) with open(DOCKERFILE_PATH, 'r', encoding='utf-8') as f: dockerfile_content = f.read() stdin, stdout, stderr = client.exec_command(f"cat > {build_dir}/Dockerfile") stdin.write(dockerfile_content) stdin.channel.shutdown_write() stdout.read() # ---- Copy JDK into context ---- print("\n[3/5] Preparing build context...") ssh_exec(client, f"cp -r /opt/jdk1.8.0_202 {build_dir}/", timeout=120) ssh_exec(client, f"du -sh {build_dir}/") # ---- Docker build ---- print("\n[4/5] Building Docker image...") out, err, code = ssh_exec(client, f"docker build -t '{full_image}' {build_dir}", timeout=300) if code != 0: print("ERROR: Docker build failed!") client.close() sys.exit(1) # ---- Push to ACR ---- print("\n[5/5] Pushing to ACR...") ssh_exec(client, f"echo '{ACR_PASS}' | docker login --username={ACR_USER} --password-stdin {ACR_REGISTRY}") out, err, code = ssh_exec(client, f"docker push '{full_image}'", timeout=600) if code != 0: print("ERROR: Docker push failed!") client.close() sys.exit(1) # ---- Verify & Cleanup ---- ssh_exec(client, f"docker images | grep '{app_name}'") ssh_exec(client, f"rm -rf {build_dir}") client.close() # ---- Summary ---- print("\n" + "=" * 60) print(" BUILD COMPLETE") print("=" * 60) print(f"\n Image Address:\n {full_image}\n") print(f" K8s Deploy:\n" f" /usr/bin/kubectl create deployment {app_name} \\\n" f" --image={full_image} -n jjb-dragon --replicas=1\n") print(f" /usr/bin/kubectl set image deployment/{app_name} \\\n" f" {app_name}={full_image} -n jjb-dragon\n") print("=" * 60) if __name__ == "__main__": main()