github.io 도 있지만 개인 보유하고 있는 Nas 를 이용해서 개인 블러그를 운영을 위해서 작성합니다.
하루 종일 이것 저것 삽질하면서 잘 안되 포기 할까도 생각했지만 오기 발동하여 결국 성공!!
Jekyll Docker 의 문서에 아주 잘 나와 있는데 Synology 에서 적용 한다고 삽질을….
간략히 내용을 정리 해보면, jekyll_home 생성 후 bundle 파일을 저장하기 위한 커스텀 폴더 생성 jekyll bundle update 를 실행하여 필요한 bundle 파일을 업데이트 후 -w 옵션을 이용한 변경 감지를 통해서 자동 정적 페이지 생성을 한다. 입니다.
Docker 저장소에서 jekyll 검색한후 jekyll/jekyll 이미지를 다운로드 합니다.
jekyll 의 원본이 위치한 경로의 접근 권한을 everyone 으로 읽기쓰기가 가능 하도록 먼저 설정합니다. 실행권한을 최고 권한으로 실행했지만 결국은 권한이 없다고 에러가.. 꼭! everyone 으로 읽기 쓰기를 설정하세요.
저는 jekyll_home 공유 폴더를 생성 후 이미 theme 를 생성한 폴더와 파일을 준비 하였습니다. 이 부분은 여기서 다루지 않을 예정입니다.
Dependencies
jekyll Docker Gemfile 의 리스트에서 의존성 파일을 설치 하게 됩니다.
Updatding & Caching
jekyll_home/vendor/bundle 폴더는 생성해주세요. Gemfile 을 제공한다면, 아래와 같이 실행 합니다.
%OUTPUT_GAME% : 젠킨스를 이용하여 빌드된 결과 파일과 배포에 필요한 파일이 있는 경로
아래 내용은 젠킨스에서 Execute Windows batch command 항목의 내용입니다.
:: GAME 압축 및 S3 업로드 작업
:: %DEPLOY_GAME%
:: %OUTPUT_GAME%
:: 압축할 파일 이름에 넣을 날짜, 시간를 설정합니다.
for /f "tokens=1,2 delims=:" %%a in ("%time%") do set hh=%%a&set mm=%%b
SET hh=%hh: =0%
:: 압축 파일 이름입니다.
SET FILENAME=Super_Game_%date:~0,4%%date:~5,2%%date:~8,2%_%hh%%mm%
:: 압축 파일 풀 경로
SET ZIPFILE=%DEPLOY_GAME%\%FILENAME%.zip
if not exist %DEPLOY_GAME%\NUL (
md %DEPLOY_GAME%
)
:: 배포용 파일 압축
D:\Jenkins\script\7za.exe a %ZIPFILE% %OUTPUT_GAME%\*.* -r -x!*.pdb
:: 버전 파일 생성
SET BUILD_INFO=%DEPLOY_GAME%\build_game.xml
@ECHO Create build_game.xml.
@ECHO ^<?xml version="1.0" encoding="utf-8"?^> > %BUILD_INFO%
@ECHO ^<File^>%FILENAME%^</File^> >> %BUILD_INFO%
cd /D %DEPLOY_GAME%
:: 생성된 파일 S3 업로드
PowerShell.exe -executionpolicy remotesigned -Command D:\Jenkins\script\upload_game_s3.ps1 -file %ZIPFILE% -path %DEPLOY_GAME% -mode "qa"
배포를 위한 S3 폴더 구성
S3 버킷의 폴더 구성은 아래의 이미지와 같습니다.
/build 이하에 각 서버별 배포 파일을 보관 할 수 있는 폴더와, 각 서버별 버전 xml 파일로 구성 되어 집니다.
Rundeck Node(Windows) 폴더 구성
배포를 위해서는 각 노드들의 경로를 통일 시켜야 합니다. Rundeck은 각노드들의 일괄 명령 처리로 동작을 하기 때문에 서버 배포 위치를 아래의 그림과 같이 드라이버 폴더 구성을 통일 시켜야 합니다.
/script : 배포에 필요한 파일들이 위치합니다. 배포 스크립트, 압축 파일등
/work : 배포 스크립트에서 사용되며, 배포 파일을 임시로 다운로드 및 압축, 백업 등에 사용됩니다.
/Gnss_Game : 게임 서버 배포가 되는 위치 입니다. 각 종 설정 파일과 게임에 필요한 파일들이 위치하며, 배포 스크립트에서 경로를 설정하면 자동 생성 됩니다.
/Gnss_Auth : 인증 서버 배포 되는 위치입니다. 게임서버와 동일하게 필요 파일들이 위치하며, 역시 스크립트에서 자동 생성됩니다.
배포를 위한 스크립트 구성
deploy_build_game.ps1 파일의 내용입니다. 아래의 스크립트를. [script] 폴더에 생성한 후에 필요 항목들을 수정 하시면 됩니다.
param([Parameter(Mandatory=$false)][string]$mode="qa")$ErrorActionPreference="Stop"$DEBUG_MODE=1# 1. Argument set #$GAME_BUILDZONE=$mode$GAME_BUILDTYPE="Super_Game"# S3 bucket set #$AWS_S3_ADDR="s3://super-build"$AWS_S3_REGION="us-east-1"# 2. define variable #write-output"."write-output"[INFO][1] Define Variable..."$TIME_CUR=Get-Date-UFormat'%Y-%m-%d %H:%M:%S'write-output"[INFO] Start TIME : $TIME_CUR"write-output"."# 2-1. get hostname #$HOSTNAME=hostname# 2-2. get date / custom type #$DATE_CUR=Get-Date-UFormat'%Y%m%d-%H%M'$TIME_CUR=Get-Date-UFormat'%Y-%m-%d %H:%M:%S'# 2-3. default PATH #$DEF_FILE_INFO="build_game.xml"$DEF_FILE_INFO_SAMPLE="build_game_sample.xml"$DEF_PATH_BASE="super"$DEF_PATH_SCRIPT="script"#$DEF_PATH_SERVER = $GAME_BUILDTYPE$DEF_PATH_BACKUP=Join-Path"work""backup"$DEF_PATH_WORK=Join-Path"work""download"$DEF_PATH_TMP=join-path"work""tmp"$DriveLetter=$PSCommandPath[0]$PATH_BASE=$DriveLetter+":\"+$DEF_PATH_BASE$PATH_SCRIPT=join-path$PATH_BASE$DEF_PATH_SCRIPT$PATH_SERVER=join-path$PATH_BASE$GAME_BUILDTYPE$PATH_SERVER_CONF=join-path$PATH_SERVER"conf"$PATH_CONF=join-path$PATH_BASE"conf_game"$PATH_BACKUP=join-path$PATH_BASE$DEF_PATH_BACKUP$PATH_WORK=join-path$PATH_BASE$DEF_PATH_WORK$PATH_WORK_SERVER=join-path$PATH_WORK$GAME_BUILDTYPE$PATH_WORK_SERVER_CONF=$PATH_WORK_SERVER$PATH_TMP=join-path$PATH_BASE$DEF_PATH_TMP$FILE_BUILD_INFO=join-path$PATH_SERVER$DEF_FILE_INFOif($DEBUG_MODE=1){write-output"[DEBUG] FILE_BUILD_INFO : $FILE_BUILD_INFO"}$FILE_BUILD_INFO_SAMPLE=join-path$PATH_SCRIPT$DEF_FILE_INFO_SAMPLEif($DEBUG_MODE=1){write-output"[DEBUG] FILE_BUILD_INFO_SAMPLE : $FILE_BUILD_INFO_SAMPLE"}$FILE_BUILD_INFO_TMP=join-path$PATH_WORK_SERVER$DEF_FILE_INFOif($DEBUG_MODE=1){write-output"[DEBUG] FILE_BUILD_INFO_TMP : $FILE_BUILD_INFO_TMP"}$PATH_S3_BUILD="$AWS_S3_ADDR/"+"$GAME_BUILDZONE/"+"build/"$PATH_S3_BUILD_CONF="$AWS_S3_ADDR/"+"$GAME_BUILDZONE/"+"conf/"$PATH_S3_SERVER="$AWS_S3_ADDR/"+"$GAME_BUILDZONE/"+"build/"+"$GAME_BUILDTYPE/"$PATH_S3_SERVER_CONF="$AWS_S3_ADDR/"+"$GAME_BUILDZONE/"+"conf/"+"$GAME_BUILDTYPE/"$FILE_S3_BUILD_INFO="$AWS_S3_ADDR/"+"$GAME_BUILDZONE/"+"build/"+"$DEF_FILE_INFO"if(!(Test-Path-Path$PATH_SERVER)){mkdir$PATH_SERVER}if(!(Test-Path-Path$PATH_BACKUP)){mkdir$PATH_BACKUP}if(!(Test-Path-Path$PATH_WORK)){mkdir$PATH_WORK}if(!(Test-Path-Path$PATH_WORK_SERVER)){mkdir$PATH_WORK_SERVER}if(!(Test-Path-Path$PATH_TMP)){mkdir$PATH_TMP}if(Test-Path$FILE_BUILD_INFO_TMP){remove-Item-force$FILE_BUILD_INFO_TMPwrite-output"[INFO] Completed for del to buildinfo.xml Temporary File"}if($DEBUG_MODE=1){write-output"[DEBUG] DEBUG MODE : On"if(Test-Path$FILE_BUILD_INFO){#remove-Item -force $FILE_BUILD_INFO}write-output"[DEBUG] Completed for del to buildinfo.xml File"}# 2. Download & Check for buildinfo.xml #write-output"."write-output"[INFO] BUILD Version Downloading & Checking Version..."write-output"."if(!(Test-Path$FILE_BUILD_INFO)){write-output"[INFO] File not found buildinfo.xml for Current BUILD"write-output"[INFO] Copy from Sample buildinfo.xml file"if(!(Test-Path-Path$PATH_SERVER)){mkdir$PATH_SERVER}copy-item$FILE_BUILD_INFO_SAMPLE$FILE_BUILD_INFO}if(!(Test-Path$FILE_BUILD_INFO_TMP)){write-output"[INFO] Download from buildinfo.xml for NEW BUILD"awss3cp--region$AWS_S3_REGION$FILE_S3_BUILD_INFO$FILE_BUILD_INFO_TMP>$nullif($DEBUG_MODE=1){write-output"[DEBUG] aws s3 cp --region $AWS_S3_REGION$FILE_S3_BUILD_INFO$FILE_BUILD_INFO_TMP"}}[xml]$xml_cur_buildinfo=get-content$FILE_BUILD_INFO$cur_ver=$xml_cur_buildinfo.File[xml]$xml_new_buildinfo=get-content$FILE_BUILD_INFO_TMP$new_ver=$xml_new_buildinfo.Filewrite-output"[INFO] +BUILD (Current Ver) = $cur_ver"write-output"[INFO] +BUILD (New Ver) = $new_ver"# -le means <=if($cur_ver-ne$new_ver){Write-output"[INFO] Deploy start"$PATH_WORK_UNZIP=join-path$PATH_WORK_SERVER$new_verif(!(Test-Path-Path$PATH_WORK_UNZIP)){mkdir$PATH_WORK_UNZIP}#Download (BUILD)write-output"."write-output"[INFO] Downloading Build..."write-output"."# "GameServer-2016110300".zip/.tar.gz/$FILENAME_BUILD="$new_ver"+".zip"if($DEBUG_MODE=1){write-output"[DEBUG] FILENAME_BUILD : $FILENAME_BUILD"}$FILE_BUILD_WORK=join-path$PATH_WORK$FILENAME_BUILDif($DEBUG_MODE=1){write-output"[DEBUG] FILE_BUILD_WORK : $FILE_BUILD_WORK"}$FILE_S3_BUILD="$PATH_S3_SERVER"+"$FILENAME_BUILD"if($DEBUG_MODE=1){write-output"[DEBUG] FILE_S3_BUILD : $FILE_S3_BUILD"}#downloadwrite-output"[INFO] Download to $FILE_S3_BUILD"awss3cp--region$AWS_S3_REGION$FILE_S3_BUILD$PATH_WORK>$nullif($DEBUG_MODE=1){write-output"[DEBUG] aws s3 cp --region $AWS_S3_REGION$FILE_S3_BUILD$PATH_WORK"}$exe_zip="$PATH_SCRIPT\unzip.exe"#uncompress#$exe_zip -x $FILE_BUILD_WORK $PATH_WORK_SERVERInvoke-Expression"& `"$exe_zip`" -o $FILE_BUILD_WORK -d $PATH_WORK_UNZIP"#Download (CONF)write-output"."write-output"[INFO] Downloading Build Configuration..."write-output"."$TARGET_PATH=join-path$PATH_WORK_UNZIP"."xcopy/E/Y$PATH_CONF\.$TARGET_PATH#aws s3 cp --region $AWS_S3_REGION --recursive $PATH_S3_SERVER_CONF $TARGET_PATH > $nullif($DEBUG_MODE=1){write-output"[DEBUG] aws s3 cp --region $AWS_S3_REGION --recursive $PATH_S3_SERVER_CONF$TARGET_PATH"}#Deploywrite-output"."write-output"[INFO] Deploying build..."write-output"."copy-item-recurse$PATH_WORK_UNZIP$PATH_SERVERwrite-output"[INFO] deploy source complted"copy-item-force$FILE_BUILD_INFO_TMP$PATH_SERVERwrite-output"[INFO] deploy buildinfo.xml complted"#cleanwrite-output"."write-output"[INFO] Cleaning Work Build..."write-output"."if(Test-Path$FILE_BUILD_INFO_TMP){remove-item-force$FILE_BUILD_INFO_TMP}if(Test-Path-Path$PATH_WORK_SERVER){remove-item-recurse-force-path$PATH_WORK_SERVER}$TIME_CUR=Get-Date-UFormat'%Y-%m-%d %H:%M:%S'write-output"[INFO] END TIME : $TIME_CUR"Write-output"[INFO] Deploy done."}else{Write-output"[INFO] Current BUILD is same or high version. Deploy cancel!!"$TIME_CUR=Get-Date-UFormat'%Y-%m-%d %H:%M:%S'write-output"[INFO] END TIME : $TIME_CUR"}
Rundeck Job 설정하기
기본적으로 배포를 위한 rundeck 프로젝트는 설정되어 있는 상태를 가정합니다.
프로젝트의 화면에서 [Create Job] 을 클릭하여, 신규 Job 을 생성합니다.
Job Name : 작업의 간략한 이름을 설정 합니다.
Description : 작업에 대한 처리 내용을 간략히 작성하여, 다른 작업자 분들이 해당 작업이 어떤 내용들을 수행하는지 작성해주시면 됩니다.
Group : 작업을을 한 그룹으로 묶어서 화면에 표시 되게 됩니다. 게임 관련 작업이면, GAME 등으로 식별이 가능한 이름을 작성하시면 됩니다.
해당 노드들에게 실행할 커맨드를 입력을 하기 위해서 [Command] 버튼을 클릭합니다.
Command : 실행할 Windows Command 명령을 입력 하시면 됩니다. 우리는 배포를 위해서 작성해 놓은 파워쉘 스크립트 파일명을 입력 하시면됩니다.
Node Filter : 위의 명령을 수행할 노드들을 선택합니다. Rundeck 노드 설정에서 입력 한 값을 이용하여, 배포할 노드들을 선택 할수 있습니다.
Matched Nodes : 입력된 필터에 맞는 결과 노드들이 표시 되며, 작업을 수행시 이 노드들에 대해서 수행을 하게 됩니다.
기본적인 입력항목은 작성이 되었습니다. 추가 적으로 작업의 성공 실패 여부를 Dooray 등으로 출력을 위해서는.
Send Notification [Yes] 를 클릭 후, Http Notification 을 선택하신 후에 항목들을 입력 하시면 됩니다.
마지막
이제 생성된 Jobs 을 이용해서 배포를 진행 하도록 하겠습니다. 위 방법으로 작업이 생성되면 아래의 그림과 같은 메뉴들을 볼수 있습니다. [GAME_DEPLOY] 를 클릭하여 배포를 진행 하도록 합니다.
배포할 Nodes 를 선택한 후 [Run Job Now] 를 클릭합니다.
정상적으로 실행된다면, 아래의 그림과 같이 수행되는 콘솔로그를 [Log Output] 탭에서 확인 할 수 있습니다.
DataInfoinfo=newDataInfo();info.Val1=1;info.Val2=1;info.Val3=1;info.Val4=1;info.Val5=1;info.Grade=1;info.Level=25;// 이 값이 대입되면, Scale 값이 이상한 값으로 셋팅됨info.AWake=1;info.Scale=1f;// 이 값이 대입되면, Level = 0, AWake = 128 으로 값이 셋팅됨
이 현상은 mono 빌드에서 발생하며, 에디터와, IL2CPP 에서는 오류 없이 정상 동작한다.
mono의 낮은 버전으로 발생되는 현상으로 보이는데, 닷넷 버전을 4.6으로 설정후 테스트 해볼 예정이다.