[PyQT5] SFTP를 이용한 만능 자동 업데이트 런처 구현


사진 출처 : https://coolenjoy.net/bbs/33/1157307?sop=and&page=3&sga=%EC%84%9C%EB%93%A0%EC%96%B4%ED%83%9D

위 게임은 "서든어택 2"의 게임 런처(실행기) 입니다. 이 게임은 말아먹은 뒤로 매일 SNS에 출시 임박 글이 올라오는 전설의 게임입니다. 대부분의 게임은 위처럼 일반적으로 * 런처라는 프로그램을 이용해서 다운로드, 업데이트, 실행 관리를 합니다. 제가 업무 자동화에 관련된 프로그램을 만들고 배포하면서 이러한 런처를 만들어야 할 상황이 생겼습니다. 매번 업데이트 하고 파일 배포하는게 정말 귀찮더라구요.

 

* 런처 : 다른 소프트웨어를 실행시키기 위해 사용하는 소프트웨어

 

제가 배포하고 있는 프로그램에 대한 런처를 만들어서 자동 업데이트 하고 실행까지 처리하면 좋을 꺼 같아서 요새 GUI 프로그래밍에 한참 사용하고 있는 PyQt5 프레임워크와 파이썬을 통해서 한번 구현해봤습니다.

 

사실 이렇게 다운로드를 받을 수 있게 하려면 업타임이 보장되는 사이트에 업로드를 해서 관리를 하거나 24시간 돌아가는 서버가 필요합니다. (뭐가 됬던 다운로드를 받기 위한 서버가 필요합니다.)

 

마침 저에겐 24시간 돌아가는 개인 NAS서버가 있는데 이를 활용해서 SFTP 같은 프로토콜을 이용해서 NAS서버에서 파일을 다운로드 받기로 했습니다.

 

해서 모든 프로그램을 배포할때 사용가능한 만능 런처를 한번 만들어 봤습니다. 사실 시험기간이라 공부에 집중해야 하지만 원래 시험기간에는 공부빼고 뭐든 재미있는 창의력이 샘솟는 시기이죠 ㅎㅎㅎ

 

How to make?

우선 NAS에 "프로그램 배포"라는 새로운 공유 폴더를 하나 만들어 줬습니다.

앞으로 런처는 이 폴더를 base로 다운로드를 진행하게 됩니다.

 

이건 예전에 만들어 놨던 SMS 자동 전송기인데, 런처에서 여기 파일을 다운 받을 경로로 지정해주면 (경로는 소스코드 맨 위에 전역 변수로써 하드코딩 되어 있습니다.) 이 파일을 받는 런처가 되는 겁니다.

 

 

서버에서 버전은 zip 파일과 같이 있는 version.txt에 관리되는데 런처가 이 version.txt를 읽어서 지금 버전과 비교를 해서 서버에서 프로그램을 받아올지 안받아 올지를 정하게 됩니다.

파일을 찾는 방법은 zip파일 중에 저 0.1이라는 문자열이 포함 되어 있나 없나 찾고 다운로드를 받습니다.

(만약 없다면 이미 받아진걸 키거나, 그것마저도 없으면 오류가 발생하면서 프로그램이 종료됩니다.)

 

물론 사진상으론 SMS 전송.zip 밖에 없으나 파일 이름을 SMS 전송 v0.1.zip 과 같이 바꿔주면 런처가 파일을 제대로 찾고 다운로드를 진행하게 됩니다.

 

여기에 파일을 쌓아두고 받을 파일만 version에 맞게 이름을 매겨주면 그 파일만 다운로드 받습니다.

여러 버전이 있어도 version.txt에서 받을것만 지정해주면 되는 방식으로 구현해뒀습니다.

 

실제 코드에서 런처를 만들기 위해 바꿔낼 것은 이 부분들입니다.

물론 개인적으로 아는 사람들한테만 배포하는 런처다보니 SFTP ID, PW가 하드 코딩으로 그대로 노출되어 있는데 사실 상업적으로 배포하기엔 조금 무리가 있을 거 같습니다.

 

만약에 이 프로그램을 인터넷에 배포한다면 SFTP ID랑 PW가 털리더라도 문제가 없도록 해야 합니다. 그러기 위해선 다운로드 받을 SFTP 계정을 NAS에서 따로 만들고 파일의 권한(Access Mode)를 프로그램 배포 폴더에서 read 권한으로 한정해줘야 그나마 좀 안전할 듯 합니다.

 

사실 SFTP이외에도 FTP, FTPS 등 다양한 프로토콜이 있었는데 그 중에서 SFTP를 사용한 이유는 사실 FTPS와 SFTP의 차이가 뭔지도 잘 모르고 인터넷에서 SFTP를 추천하길래 선택했습니다 ㅋㅋ.

시놀로지에서는 그냥 SFTP 설정만 켜주면 접속이 되기 때문에... 복잡하게 생각하진 않았네요

 

 

어쨌든 런처를 켜주면 현재 경로에 version.txt 파일의 유무를 체크하고 서버에서 다운로드를 받아서 자동 업데이트를 진행해줍니다. 업데이트가 필요 없으면 받아진 프로그램을 그대로 켜주는 방식대로 진행했구요.

 

런처가 파일을 받을땐 아까 zip 파일을 받고 자동 압축해제, 프로그램 자동 실행까지 진행해줍니다.

(폴더가 아닌 zip 파일을 받는 방식으로 구현한 이유는 조금이라도 더 빨리 받기 위함입니다. 서버에서 짜잘한 파일 10000개를 하나 하나씩 받는것보단, 귀찮더라도 압축 시간만 한번 기다리고 서버에 업로드 해주면 받을땐 zip 단일 파일 1개만 받는게 당연하지만 훠~얼씬 빠릅니다.)

 

원하는 대로 구현이 잘 된거 같아서 기분이 좋네요 ㅎㅎ 아마 C#으로 구현했으면 쓰레드 부분에서 delegate 같은 처리를 해주느라 시간이 한참 소요되지 않았을까 싶습니다... 파이썬으로 만들어서 엄청난 생산성으로 후딱 개발을 끝냈습니다.

 

 

마음에 안드는건 항상 그렇듯이 pyinstaller를 통해 exe로 바꿨을때... C# 이랑 비교해서 용량이 몇백배 차이 난다는거 ㅠ (C#으로 이런거 만들면 보통 1mb도 안하고 kb단위로 끝납니다.)

 

이건 인터프리터 언어의 한계니 어쩔 수 없겠지요 ^^;; 그래도 요새 프로그램도 기본 몇백 MB를 넘어가고 게임은 100gb 단위까지 가는 시대니깐... 뭐 이정도야 괜찮다고 봅니다 ㅎㅎ 일단은 프로그램 완성이 되야 되니깐요.

 

COMMENT WRITE