效果
起因
現在springboot項目的自動化部署已經非常普遍,有用Jenkins的,有用git鉤子函數的,有用docker的…等等。這段時間在玩python,想著用python實現自動化部署,即能鍛煉下編碼能力,又方便運維。于是開始著手寫了一個exe程序,可直接在任何windows電腦上運行(不具備python環境的windows電腦也可以運行)。有興趣的小伙伴可以跟著代碼一起練一練噢,寫的詳細一點,對python新手也很友好。
實現步驟
開發準備
- 具有python基本環境和ide的windows或macOS電腦一臺
- 安裝打包工具
pip install pyinstaller
- 一點小小的python基礎
步驟
1. 導入依賴
新建一個py文件,可以把它命名為 deployment.py(名字隨意哈,什么名兒都可以),然后把下面的庫導入語句copy到此py文件中
import os #用于-提取文件名
import re #用于-正則表達式
import time #用于-線程休眠
import paramiko #用于-遠程執行linux命令
from alive_progress import alive_bar #用于-進度條工具類
from cryptography.fernet import Fernet #用于-加解密代碼
import base64 #用于-加解密代碼
import hashlib #用于-加解密代碼
在導入依賴的時候,可能有些依賴咱們的電腦上之前沒下載過,不要緊,只需要在pycharm中按 alt+enter就可以自動導入了,PyCharm跟Idea的快捷鍵一模一樣,可以按Idea的習慣使用。而且在python中還不用配置maven或pom文件,非常方便。
2. 輸入校驗
部署畢竟是件嚴謹的事情,我們增加個部署密鑰校驗,我的這個部署密鑰承擔了以下的功能
- 確保部署的安全性,不是誰拿到這個exe程序都能運行的(哼~傲嬌)
- 密鑰字符串用-分割開,前面的區分環境,后面的區分項目或模塊。
- 如果同學們不需要區分項目子模塊,就不需要搞這么復雜,隨便定義一個密鑰就好了
import os #用于-提取文件名
import re #用于-正則表達式
import time #用于-線程休眠
import paramiko #用于-遠程執行linux命令
from alive_progress import alive_bar #用于-進度條工具類
from cryptography.fernet import Fernet #用于-加解密代碼
import base64 #用于-加解密代碼
import hashlib #用于-加解密代碼 #檢查密鑰格式
def check_deploy_sign(deploy_site): #確保密鑰只能是以下4個之一才能繼續往下操作,否則無限循環輸入 或 退出程序if deploy_site != 'pro-main' and deploy_site != 'pro-manage' and deploy_site != 'test-main' and deploy_site != 'test-manage': #校驗失敗,一直校驗new_deploy_site = input("錯誤:請填寫部署密鑰:") check_deploy_sign(new_deploy_site) #校驗成功,退出return deploy_site try: deploy_sign = input("提示:請填寫部署密鑰:") deploy_sign = check_deploy_sign(deploy_sign) # 部署環境 pro代表生成環境,test代表測試環境deploy_server = deploy_sign.split('-')[0] # 部署模塊或項目 manage代表manage模塊,main代表main模塊, deploy_site = deploy_sign.split('-')[1] # 打包時的包名,三目運算符package_name = 'production' if deploy_server == 'pro' else 'staging' except Exception as e: print(f"異常: {str(e)}")
上面的代碼中 增加了全局的異常處理,類似Java的try catch,也定義了一些基本的變量。密鑰是一串由短線連接的字符串,短線前的代碼用以區分環境,短線后的代碼用以區分模塊或項目。另外上面代碼中的package_name是打包時的包名(即profiles.profile.id),一般配置在springboot項目pom文件中的編輯模塊,類似下面這樣:
3. 連接linux服務器
import os #用于-提取文件名
import re #用于-正則表達式
import time #用于-線程休眠
import paramiko #用于-遠程執行linux命令
from alive_progress import alive_bar #用于-進度條工具類
from cryptography.fernet import Fernet #用于-加解密代碼
import base64 #用于-加解密代碼
import hashlib #用于-加解密代碼 #檢查密鑰格式
def check_deploy_sign(deploy_site): #確保密鑰只能是以下4個之一才能繼續往下操作,否則無限循環輸入 或 退出程序if deploy_site != 'pro-main' and deploy_site != 'pro-manage' and deploy_site != 'test-main' and deploy_site != 'test-manage': #校驗失敗,一直校驗new_deploy_site = input("錯誤:請填寫部署密鑰:") check_deploy_sign(new_deploy_site) #校驗成功,退出return deploy_site # 連接服務器
def connect_service(deploy_server):server_password = '' server_host = '' sign = hashlib.sha256(deploy_server.encode()).digest() sign = base64.urlsafe_b64encode(sign) if deploy_server == 'pro': server_password = decrypt_str(sign, service_password_pro) server_host = decrypt_str(sign, service_host_pro) elif deploy_server == 'test': server_password = decrypt_str(sign, service_password_test) server_host = decrypt_str(sign, service_host_test) else: raise Exception('失敗:部署服務器標識有誤') # 連接遠程服務器 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(server_host, username='root', password=server_password) return ssh # 解密密碼
def decrypt_str(key, encrypted_password): f = Fernet(key) decrypted_password = f.decrypt(encrypted_password).decode() return decrypted_passwordtry: # 服務器環境信息的加密字符串,包含各服務器的 ip和密碼 service_password_pro = 'asdatrgsd==' service_password_test = 'sgherfhdf==' service_host_pro = 'jfhgfvdcfdtr==' service_host_test = 'jutyrbfvret=='deploy_sign = input("提示:請填寫部署密鑰:") deploy_sign = check_deploy_sign(deploy_sign) # 部署環境 pro代表生成環境,test代表測試環境deploy_server = deploy_sign.split('-')[0] # 部署模塊或項目 manage代表manage模塊,main代表main模塊, deploy_site = deploy_sign.split('-')[1] # 打包時的包名,三目運算符package_name = 'production' if deploy_server == 'pro' else 'staging' #進度條with alive_bar(7, force_tty=True, title="進度") as bar: # 連接服務器 ssh = connect_service(deploy_server) bar(0.1) print("完成-服務器連接成功") time.sleep(0.5)
except Exception as e: print(f"異常: {str(e)}")
在連接服務器之前,我們加個進度條顯示,方便查看部署到哪一步了,要點講解:
- with alive_bar 中放的事需要進度條顯示的步驟,connect_service是連接服務器的方法
- 主機的ip和密碼我們用加密的密文顯示,解密的密鑰就是 手動輸入的部署密鑰
- 當一段邏輯執行完成后,通過bar(0.1)來顯示進度條進度,alive_bar的第一個參數就是步驟總數
4. 部署工具主邏輯
代碼要點講解: 下面的代碼是工程的全部代碼,主要包含了以下邏輯
- 連接服務器
- 進入到項目工程目錄,拉取git代碼
- 編譯公共依賴的代碼(有的項目不一定有公共模塊,可酌情刪減)
- 編譯打包程序代碼
- 殺死舊進程
- 尋找編譯好的程序jar包并啟動
- 檢測啟動結果
import os #用于-提取文件名
import re #用于-正則表達式
import time #用于-線程休眠
import paramiko #用于-遠程執行linux命令
from alive_progress import alive_bar #用于-進度條工具類
from cryptography.fernet import Fernet #用于-加解密代碼
import base64 #用于-加解密代碼
import hashlib #用于-加解密代碼def check_deploy_sign(deploy_site):if deploy_site != 'pro-main' and deploy_site != 'pro-manage' and deploy_site != 'test-main' and deploy_site != 'test-manage':new_deploy_site = input("錯誤:請填寫部署密鑰:")check_deploy_sign(new_deploy_site)return deploy_site# 解密密碼
def decrypt_str(key, encrypted_password):f = Fernet(key)decrypted_password = f.decrypt(encrypted_password).decode()return decrypted_password# 執行遠程命令
def execute_command(ssh, command):stdin, stdout, stderr = ssh.exec_command(command)stdout.channel.recv_exit_status() # 等待命令執行完畢output = stdout.read().decode('utf-8')time.sleep(0.5)return output# 執行遠程命令
def execute_command_shell(shell, command, endword):shell.send(command + '\n')output = ''while True:while shell.recv_ready():recv = shell.recv(1024).decode('utf-8', errors='ignore')output += recvif endword == '# ':if output.endswith('$ ') or output.endswith('# '):breakelif endword in output:breaktime.sleep(0.5)return output# 連接服務器
def connect_service(deploy_server): server_password = ''server_host = ''sign = hashlib.sha256(deploy_server.encode()).digest()sign = base64.urlsafe_b64encode(sign)if deploy_server == 'pro':server_password = decrypt_str(sign, service_password_pro)server_host = decrypt_str(sign, service_host_pro)elif deploy_server == 'test':server_password = decrypt_str(sign, service_password_test)server_host = decrypt_str(sign, service_host_test)else:raise Exception('失敗:部署服務器標識有誤')# 連接遠程服務器ssh = paramiko.SSHClient()ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect(server_host, username='root', password=server_password)return ssh# 查詢進程
def query_process(ssh, process_name): process_id = ''command = f"ps -ef | grep {process_name}-system-master. | grep -v grep"process_output = execute_command(ssh, command)if process_output:# 提取進程ID并殺死進程process_id = process_output.split(" ")[1]return process_id# 殺掉進程
def kill_process(ssh, process_id): command = f"kill -9 {process_id}"output = execute_command(ssh, command)return output# 尋找編譯好的jar包
def find_jarname(output):match = re.search(r"Building jar: .+?\/(.+?\.jar)", output)if match:jar_filepath = match.group(1)jar_filename = os.path.basename(jar_filepath)return jar_filenameelse:raise Exception('失敗:jar未找到')try:service_password_pro = 'asdatrgsd=='service_password_test = 'sgherfhdf=='service_host_pro = 'jfhgfvdcfdtr=='service_host_test = 'jutyrbfvret=='deploy_sign = input("提示:請填寫部署密鑰:")deploy_sign = check_deploy_sign(deploy_sign)# 部署環境deploy_server = deploy_sign.split('-')[0]# 部署模塊deploy_site = deploy_sign.split('-')[1]# 部署環境對應服務正式的名字package_name = 'production' if deploy_server == 'pro' else 'staging'with alive_bar(7, force_tty=True, title="進度") as bar:# 連接服務器ssh = connect_service(deploy_server)bar(0.1)print("完成-服務器連接成功")time.sleep(0.5)# 拉取代碼shell = ssh.invoke_shell()execute_command_shell(shell, 'cd /root/build/x-system','#')execute_command_shell(shell, 'git pull','#')bar(0.2)print("完成-git代碼拉取成功")# 編譯代碼execute_command_shell(shell, 'cd /root/build/x-system/modules', '#')execute_command_shell(shell, 'mvn clean install', 'BUILD SUCCESS')bar(0.4)print("完成-公共模塊編譯成功")# 打包代碼execute_command_shell(shell, 'cd /root/build/x-system/webapps/' + deploy_site + '-system ', '#')output=execute_command_shell(shell, 'mvn clean package -P ' + package_name, 'BUILD SUCCESS')bar(0.6)print("完成-" + deploy_site + "模塊打包成功")# 查詢進程,如果查不到 就不執行kill命令pid = query_process(ssh, deploy_site)if pid != '':kill_process(ssh, pid)print("完成-舊程序進程已被殺掉,等待啟動")else:print("完成-舊程序PID未找到,直接啟動")bar(0.7)# 啟動jarjar_name = find_jarname(output)execute_command_shell(shell, 'cd /root/build/x-system/webapps/' + deploy_site + '-system/target', '#')execute_command_shell(shell, 'nohup java -jar ' + jar_name + '>log.out 2>&1 & ', '#')bar(0.8)print("完成-程序正在啟動中...")# 查看日志確認服務啟動成功log_path = '/var/log/x-system/' + deploy_site + '-system' if deploy_server == 'pro' else '/var/log/x-system/' + deploy_site + '-system-staging'execute_command_shell(shell, 'cd '+log_path, '#')execute_command_shell(shell, 'tail -200f '+deploy_site+'-system-info.log', 'TomcatWebServer:206 - Tomcat started on port(s)')bar(1)print("完成-程序啟動成功")
except Exception as e:print(f"異常: {str(e)}")finally:time.sleep(10)# 關閉連接shell.close()ssh.close()
代碼用try catch finally包裹,如果過程中出現任何異常,都輸出錯誤原因 一些提示:
- 每個人的項目服務器的路徑都不同,我只是提供個例子,不可盲目復制運行
- 每個人項目的名字也不同,我在文中出現類似 manage和main,是我項目模塊中的名字,只是個例子,不可盲目復制
5.打包
打包命令:
pyinstaller --onefile --icon 太空人.ico --add-data ".\grapheme_break_property.json;grapheme\data" --name 遠程部署 deployment.py
打包命令中的幾個參數解釋一下:
- –onefile :將項目工程文件輸出在同一個可執行文件中即exe中
- –icon 太空人.ico :exe的圖標是一個ico的圖片
- –add-data “.\grapheme_break_property.json;grapheme\data” : 打包時 grapheme_break_property這個依賴找不到,導致打包失敗,就手動添加一下
- –name 遠程部署 :exe的名字(注意不需要帶.exe后綴)
- deployment.py :python工程的文件名
結語
python很好玩,希望大家玩的開心!
如果你對Python感興趣,想要學習python,這里給大家分享一份Python全套學習資料,都是我自己學習時整理的,希望可以幫到你,一起加油!
😝有需要的小伙伴,可以V掃描下方二維碼免費領取🆓
?
1??零基礎入門
① 學習路線
對于從來沒有接觸過Python的同學,我們幫你準備了詳細的學習成長路線圖。可以說是最科學最系統的學習路線,你可以按照上面的知識點去找對應的學習資源,保證自己學得較為全面。
② 路線對應學習視頻
還有很多適合0基礎入門的學習視頻,有了這些視頻,輕輕松松上手Python~
③練習題
每節視頻課后,都有對應的練習題哦,可以檢驗學習成果哈哈!
2??國內外Python書籍、文檔
① 文檔和書籍資料
3??Python工具包+項目源碼合集
①Python工具包
學習Python常用的開發軟件都在這里了!每個都有詳細的安裝教程,保證你可以安裝成功哦!
②Python實戰案例
光學理論是沒用的,要學會跟著一起敲代碼,動手實操,才能將自己的所學運用到實際當中去,這時候可以搞點實戰案例來學習。100+實戰案例源碼等你來拿!
③Python小游戲源碼
如果覺得上面的實戰案例有點枯燥,可以試試自己用Python編寫小游戲,讓你的學習過程中增添一點趣味!
4??Python面試題
我們學會了Python之后,有了技能就可以出去找工作啦!下面這些面試題是都來自阿里、騰訊、字節等一線互聯網大廠,并且有阿里大佬給出了權威的解答,刷完這一套面試資料相信大家都能找到滿意的工作。
上述所有資料 ?? ,朋友們如果有需要的,可以掃描下方👇👇👇二維碼免費領取🆓
?
效果
起因
現在springboot項目的自動化部署已經非常普遍,有用Jenkins的,有用git鉤子函數的,有用docker的…等等。這段時間在玩python,想著用python實現自動化部署,即能鍛煉下編碼能力,又方便運維。于是開始著手寫了一個exe程序,可直接在任何windows電腦上運行(不具備python環境的windows電腦也可以運行)。有興趣的小伙伴可以跟著代碼一起練一練噢,寫的詳細一點,對python新手也很友好。
實現步驟
開發準備
- 具有python基本環境和ide的windows或macOS電腦一臺
- 安裝打包工具
pip install pyinstaller
- 一點小小的python基礎
步驟
1. 導入依賴
新建一個py文件,可以把它命名為 deployment.py(名字隨意哈,什么名兒都可以),然后把下面的庫導入語句copy到此py文件中
import os #用于-提取文件名
import re #用于-正則表達式
import time #用于-線程休眠
import paramiko #用于-遠程執行linux命令
from alive_progress import alive_bar #用于-進度條工具類
from cryptography.fernet import Fernet #用于-加解密代碼
import base64 #用于-加解密代碼
import hashlib #用于-加解密代碼
在導入依賴的時候,可能有些依賴咱們的電腦上之前沒下載過,不要緊,只需要在pycharm中按 alt+enter就可以自動導入了,PyCharm跟Idea的快捷鍵一模一樣,可以按Idea的習慣使用。而且在python中還不用配置maven或pom文件,非常方便。
2. 輸入校驗
部署畢竟是件嚴謹的事情,我們增加個部署密鑰校驗,我的這個部署密鑰承擔了以下的功能
- 確保部署的安全性,不是誰拿到這個exe程序都能運行的(哼~傲嬌)
- 密鑰字符串用-分割開,前面的區分環境,后面的區分項目或模塊。
- 如果同學們不需要區分項目子模塊,就不需要搞這么復雜,隨便定義一個密鑰就好了
import os #用于-提取文件名
import re #用于-正則表達式
import time #用于-線程休眠
import paramiko #用于-遠程執行linux命令
from alive_progress import alive_bar #用于-進度條工具類
from cryptography.fernet import Fernet #用于-加解密代碼
import base64 #用于-加解密代碼
import hashlib #用于-加解密代碼 #檢查密鑰格式
def check_deploy_sign(deploy_site): #確保密鑰只能是以下4個之一才能繼續往下操作,否則無限循環輸入 或 退出程序if deploy_site != 'pro-main' and deploy_site != 'pro-manage' and deploy_site != 'test-main' and deploy_site != 'test-manage': #校驗失敗,一直校驗new_deploy_site = input("錯誤:請填寫部署密鑰:") check_deploy_sign(new_deploy_site) #校驗成功,退出return deploy_site try: deploy_sign = input("提示:請填寫部署密鑰:") deploy_sign = check_deploy_sign(deploy_sign) # 部署環境 pro代表生成環境,test代表測試環境deploy_server = deploy_sign.split('-')[0] # 部署模塊或項目 manage代表manage模塊,main代表main模塊, deploy_site = deploy_sign.split('-')[1] # 打包時的包名,三目運算符package_name = 'production' if deploy_server == 'pro' else 'staging' except Exception as e: print(f"異常: {str(e)}")
上面的代碼中 增加了全局的異常處理,類似Java的try catch,也定義了一些基本的變量。密鑰是一串由短線連接的字符串,短線前的代碼用以區分環境,短線后的代碼用以區分模塊或項目。另外上面代碼中的package_name是打包時的包名(即profiles.profile.id),一般配置在springboot項目pom文件中的編輯模塊,類似下面這樣:
3. 連接linux服務器
import os #用于-提取文件名
import re #用于-正則表達式
import time #用于-線程休眠
import paramiko #用于-遠程執行linux命令
from alive_progress import alive_bar #用于-進度條工具類
from cryptography.fernet import Fernet #用于-加解密代碼
import base64 #用于-加解密代碼
import hashlib #用于-加解密代碼 #檢查密鑰格式
def check_deploy_sign(deploy_site): #確保密鑰只能是以下4個之一才能繼續往下操作,否則無限循環輸入 或 退出程序if deploy_site != 'pro-main' and deploy_site != 'pro-manage' and deploy_site != 'test-main' and deploy_site != 'test-manage': #校驗失敗,一直校驗new_deploy_site = input("錯誤:請填寫部署密鑰:") check_deploy_sign(new_deploy_site) #校驗成功,退出return deploy_site # 連接服務器
def connect_service(deploy_server):server_password = '' server_host = '' sign = hashlib.sha256(deploy_server.encode()).digest() sign = base64.urlsafe_b64encode(sign) if deploy_server == 'pro': server_password = decrypt_str(sign, service_password_pro) server_host = decrypt_str(sign, service_host_pro) elif deploy_server == 'test': server_password = decrypt_str(sign, service_password_test) server_host = decrypt_str(sign, service_host_test) else: raise Exception('失敗:部署服務器標識有誤') # 連接遠程服務器 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(server_host, username='root', password=server_password) return ssh # 解密密碼
def decrypt_str(key, encrypted_password): f = Fernet(key) decrypted_password = f.decrypt(encrypted_password).decode() return decrypted_passwordtry: # 服務器環境信息的加密字符串,包含各服務器的 ip和密碼 service_password_pro = 'asdatrgsd==' service_password_test = 'sgherfhdf==' service_host_pro = 'jfhgfvdcfdtr==' service_host_test = 'jutyrbfvret=='deploy_sign = input("提示:請填寫部署密鑰:") deploy_sign = check_deploy_sign(deploy_sign) # 部署環境 pro代表生成環境,test代表測試環境deploy_server = deploy_sign.split('-')[0] # 部署模塊或項目 manage代表manage模塊,main代表main模塊, deploy_site = deploy_sign.split('-')[1] # 打包時的包名,三目運算符package_name = 'production' if deploy_server == 'pro' else 'staging' #進度條with alive_bar(7, force_tty=True, title="進度") as bar: # 連接服務器 ssh = connect_service(deploy_server) bar(0.1) print("完成-服務器連接成功") time.sleep(0.5)
except Exception as e: print(f"異常: {str(e)}")
在連接服務器之前,我們加個進度條顯示,方便查看部署到哪一步了,要點講解:
- with alive_bar 中放的事需要進度條顯示的步驟,connect_service是連接服務器的方法
- 主機的ip和密碼我們用加密的密文顯示,解密的密鑰就是 手動輸入的部署密鑰
- 當一段邏輯執行完成后,通過bar(0.1)來顯示進度條進度,alive_bar的第一個參數就是步驟總數
4. 部署工具主邏輯
代碼要點講解: 下面的代碼是工程的全部代碼,主要包含了以下邏輯
- 連接服務器
- 進入到項目工程目錄,拉取git代碼
- 編譯公共依賴的代碼(有的項目不一定有公共模塊,可酌情刪減)
- 編譯打包程序代碼
- 殺死舊進程
- 尋找編譯好的程序jar包并啟動
- 檢測啟動結果
import os #用于-提取文件名
import re #用于-正則表達式
import time #用于-線程休眠
import paramiko #用于-遠程執行linux命令
from alive_progress import alive_bar #用于-進度條工具類
from cryptography.fernet import Fernet #用于-加解密代碼
import base64 #用于-加解密代碼
import hashlib #用于-加解密代碼def check_deploy_sign(deploy_site):if deploy_site != 'pro-main' and deploy_site != 'pro-manage' and deploy_site != 'test-main' and deploy_site != 'test-manage':new_deploy_site = input("錯誤:請填寫部署密鑰:")check_deploy_sign(new_deploy_site)return deploy_site# 解密密碼
def decrypt_str(key, encrypted_password):f = Fernet(key)decrypted_password = f.decrypt(encrypted_password).decode()return decrypted_password# 執行遠程命令
def execute_command(ssh, command):stdin, stdout, stderr = ssh.exec_command(command)stdout.channel.recv_exit_status() # 等待命令執行完畢output = stdout.read().decode('utf-8')time.sleep(0.5)return output# 執行遠程命令
def execute_command_shell(shell, command, endword):shell.send(command + '\n')output = ''while True:while shell.recv_ready():recv = shell.recv(1024).decode('utf-8', errors='ignore')output += recvif endword == '# ':if output.endswith('$ ') or output.endswith('# '):breakelif endword in output:breaktime.sleep(0.5)return output# 連接服務器
def connect_service(deploy_server): server_password = ''server_host = ''sign = hashlib.sha256(deploy_server.encode()).digest()sign = base64.urlsafe_b64encode(sign)if deploy_server == 'pro':server_password = decrypt_str(sign, service_password_pro)server_host = decrypt_str(sign, service_host_pro)elif deploy_server == 'test':server_password = decrypt_str(sign, service_password_test)server_host = decrypt_str(sign, service_host_test)else:raise Exception('失敗:部署服務器標識有誤')# 連接遠程服務器ssh = paramiko.SSHClient()ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect(server_host, username='root', password=server_password)return ssh# 查詢進程
def query_process(ssh, process_name): process_id = ''command = f"ps -ef | grep {process_name}-system-master. | grep -v grep"process_output = execute_command(ssh, command)if process_output:# 提取進程ID并殺死進程process_id = process_output.split(" ")[1]return process_id# 殺掉進程
def kill_process(ssh, process_id): command = f"kill -9 {process_id}"output = execute_command(ssh, command)return output# 尋找編譯好的jar包
def find_jarname(output):match = re.search(r"Building jar: .+?\/(.+?\.jar)", output)if match:jar_filepath = match.group(1)jar_filename = os.path.basename(jar_filepath)return jar_filenameelse:raise Exception('失敗:jar未找到')try:service_password_pro = 'asdatrgsd=='service_password_test = 'sgherfhdf=='service_host_pro = 'jfhgfvdcfdtr=='service_host_test = 'jutyrbfvret=='deploy_sign = input("提示:請填寫部署密鑰:")deploy_sign = check_deploy_sign(deploy_sign)# 部署環境deploy_server = deploy_sign.split('-')[0]# 部署模塊deploy_site = deploy_sign.split('-')[1]# 部署環境對應服務正式的名字package_name = 'production' if deploy_server == 'pro' else 'staging'with alive_bar(7, force_tty=True, title="進度") as bar:# 連接服務器ssh = connect_service(deploy_server)bar(0.1)print("完成-服務器連接成功")time.sleep(0.5)# 拉取代碼shell = ssh.invoke_shell()execute_command_shell(shell, 'cd /root/build/x-system','#')execute_command_shell(shell, 'git pull','#')bar(0.2)print("完成-git代碼拉取成功")# 編譯代碼execute_command_shell(shell, 'cd /root/build/x-system/modules', '#')execute_command_shell(shell, 'mvn clean install', 'BUILD SUCCESS')bar(0.4)print("完成-公共模塊編譯成功")# 打包代碼execute_command_shell(shell, 'cd /root/build/x-system/webapps/' + deploy_site + '-system ', '#')output=execute_command_shell(shell, 'mvn clean package -P ' + package_name, 'BUILD SUCCESS')bar(0.6)print("完成-" + deploy_site + "模塊打包成功")# 查詢進程,如果查不到 就不執行kill命令pid = query_process(ssh, deploy_site)if pid != '':kill_process(ssh, pid)print("完成-舊程序進程已被殺掉,等待啟動")else:print("完成-舊程序PID未找到,直接啟動")bar(0.7)# 啟動jarjar_name = find_jarname(output)execute_command_shell(shell, 'cd /root/build/x-system/webapps/' + deploy_site + '-system/target', '#')execute_command_shell(shell, 'nohup java -jar ' + jar_name + '>log.out 2>&1 & ', '#')bar(0.8)print("完成-程序正在啟動中...")# 查看日志確認服務啟動成功log_path = '/var/log/x-system/' + deploy_site + '-system' if deploy_server == 'pro' else '/var/log/x-system/' + deploy_site + '-system-staging'execute_command_shell(shell, 'cd '+log_path, '#')execute_command_shell(shell, 'tail -200f '+deploy_site+'-system-info.log', 'TomcatWebServer:206 - Tomcat started on port(s)')bar(1)print("完成-程序啟動成功")
except Exception as e:print(f"異常: {str(e)}")finally:time.sleep(10)# 關閉連接shell.close()ssh.close()
代碼用try catch finally包裹,如果過程中出現任何異常,都輸出錯誤原因 一些提示:
- 每個人的項目服務器的路徑都不同,我只是提供個例子,不可盲目復制運行
- 每個人項目的名字也不同,我在文中出現類似 manage和main,是我項目模塊中的名字,只是個例子,不可盲目復制
5.打包
打包命令:
pyinstaller --onefile --icon 太空人.ico --add-data ".\grapheme_break_property.json;grapheme\data" --name 遠程部署 deployment.py
打包命令中的幾個參數解釋一下:
- –onefile :將項目工程文件輸出在同一個可執行文件中即exe中
- –icon 太空人.ico :exe的圖標是一個ico的圖片
- –add-data “.\grapheme_break_property.json;grapheme\data” : 打包時 grapheme_break_property這個依賴找不到,導致打包失敗,就手動添加一下
- –name 遠程部署 :exe的名字(注意不需要帶.exe后綴)
- deployment.py :python工程的文件名
結語
python很好玩,希望大家玩的開心!
如果你對Python感興趣,想要學習python,這里給大家分享一份Python全套學習資料,都是我自己學習時整理的,希望可以幫到你,一起加油!
😝有需要的小伙伴,可以V掃描下方二維碼免費領取🆓
?
1??零基礎入門
① 學習路線
對于從來沒有接觸過Python的同學,我們幫你準備了詳細的學習成長路線圖。可以說是最科學最系統的學習路線,你可以按照上面的知識點去找對應的學習資源,保證自己學得較為全面。
② 路線對應學習視頻
還有很多適合0基礎入門的學習視頻,有了這些視頻,輕輕松松上手Python~
③練習題
每節視頻課后,都有對應的練習題哦,可以檢驗學習成果哈哈!
2??國內外Python書籍、文檔
① 文檔和書籍資料
3??Python工具包+項目源碼合集
①Python工具包
學習Python常用的開發軟件都在這里了!每個都有詳細的安裝教程,保證你可以安裝成功哦!
②Python實戰案例
光學理論是沒用的,要學會跟著一起敲代碼,動手實操,才能將自己的所學運用到實際當中去,這時候可以搞點實戰案例來學習。100+實戰案例源碼等你來拿!
③Python小游戲源碼
如果覺得上面的實戰案例有點枯燥,可以試試自己用Python編寫小游戲,讓你的學習過程中增添一點趣味!
4??Python面試題
我們學會了Python之后,有了技能就可以出去找工作啦!下面這些面試題是都來自阿里、騰訊、字節等一線互聯網大廠,并且有阿里大佬給出了權威的解答,刷完這一套面試資料相信大家都能找到滿意的工作。
上述所有資料 ?? ,朋友們如果有需要的,可以掃描下方👇👇👇二維碼免費領取🆓
?