이제 Buildr 시리즈도 막바지를 향해 달려가는군요. 이번에는 빌드 결과물을 원격의 서버에 배포해보겠습니다.
Maven에 install, deploy 단계(phase)가 있는 것처럼 Buildr에도 배포와 관련된 install, upload, release 타스크가 있습니다만, 일반적인 웹어플리케이션 개발 프로젝트에서는 그닥 쓸모가 없습니다. 웹어플리케이션 프로젝트에서 배포는 대부분 WAS에 deploy하는 것을 의미하기 때문입니다.

로컬 WAS에 배포하는 건 간단하니 넘어가고, 리모트에 있는 개발서버나 운영서버에 우리가 빌드한 어플리케이션을 전송하는 방법을 알아보겠습니다.

요즘은 원격 서버에 연결하기 위한 프로토콜로 거의 ssh, scp를 이용합니다. Ant에서는 ssh,scp 프로토콜로 원격 서버에 연결하기 위해서 흔히 jsch 라이브러리를 사용했죠. Buildr에서는 net-ssh, net-scp 라이브러리를 사용하여 이런 작업을 처리합니다. 

먼저 profiles.yaml에 다음처럼 WAS 서버에 대한 접속정보가 설정되어 있습니다(이건 예제입니다).

development:
  wasserver:
    host: 111.111.111.111
    username: weblogic
    password: weblogic
    deploy_dir: /home/weblogic/webapps
    restart: sh /home/weblogic/restart.sh

production:
  wasserver:
    host: 222.222.222.222
    username: prod
    password: prod
    deploy_dir: /home/prod/webapps
    restart: sh /home/prod/restart.sh

WAS 서버에 웹어플리케이션을 업로드하는 타스크는 아래와 같이 작성할 수 있습니다. Net::SCP.start 메소드에 접속정보를 넘겨주고 블록 안에서 scp의 upload 메소드를 이용하여 'target/webapp' 디렉토리를 업로드하고 있습니다.

task :deploy_webapp => :package do
  require 'net/ssh'
  require 'net/scp' 

  wasserver = Buildr.settings.profile['wasserver']
  Net::SCP.start(wasserver['host'], wasserver['username'],
                       :password => wasserver['password']) do |scp|
    scp.upload!('target/webapp',  wasserver['deploy_dir'], :preserve=>true, :recursive=>true) 
  end
end

이렇게 업로드하면 로컬의 target/webapp/index.jsp 파일은 원격의 /home/weblogic/webapps/webapp/index.jsp에 위치하게 됩니다. 그러니까 로컬의 webapp 디렉토리 자체가 원격 타겟 디렉토리 밑으로 들어갑니다. 아 이건 우리가 원하는게 아닙니다. target/webapp 디렉토리는 빼고, 그 밑의 파일/디렉토리들만 원격 타겟 디렉토리 밑으로 보내고 싶습니다. 고민할 필요없이 FileList를 이용하면 됩니다.

FileList['target/webapp/*'].each do |file|
  scp.upload! file, file.sub('target/webapp',wasserver['deploy_dir']),:preserve=>true,:recursive=>true
end

exploded 모드로 빌드된 target/webapp 디렉토리 말고 그냥 하나의 패키징된 war 파일을 업로드하는 건 어떨까요? 

  scp.upload! package(:war).name, wasserver['deploy_dir'], :preserve=>true

패키징된 war 파일의 이름은 package(:war).name 로 구할 수 있었습니다. 무지 쉽군요. 

실제 실행해보시면 알겠지만, 이렇게 원격으로 업로드 시 콘솔에는 아무 것도 찍히지 않습니다. 재미가 없죠. 지금 어떤 파일이 전송되고 있는지 최소한 파일 이름이라도 나와주면 좋을 겁니다. 업로드 진행현황은 upload 메소드에 블록을 넘겨주어 표현할 수 있습니다. 다음은 업로드되는 파일의 이름과 파일의 전체 크기를 출력하는 예제입니다.

scp.upload!(package(:war).name, 
                 wasserver['deploy_dir'],
                 :preserve=>true) do |ch, name, sent, total|
  puts "uploading #{name} (#{total} byte)" if sent == 0
end

음... 전송파일의 크기가 큰 경우에는 콘솔에 변화가 별로 없으니 이것도 솔직히 별로 재미가 없습니다. 좀더 다이내믹하게 진짜로 현재의 업로드 진행 현황을 막대그래프에 #이나 * 문자가 늘어나는 식으로 보여주면 좋겠는데....
Buildr에서 메이븐 저장소에서 아티팩트를 다운로드 받을 때 다운로드 그래프가 나온다는 사실을 떠올리며 Buildr 소스를 여기저기 까보다가 ProgressBar 클래스를 발견했습니다. 나름 쓸만하네요.

local_file = package(:war).name
remote_dir = wasserver['deploy_dir']

ProgressBar.start :total=>File.size(local_file),:title=>local_file do |progress|
  scp.upload!(local_file, remote_dir, :preserve=>true) do  |ch, name, sent, total|
    progress.inc sent
  end
end

콘솔에 이렇게 출력됩니다.


웹어플리케이션을 업로드했으니, WAS를 재기동해볼까요? 서버에 있는 WAS를 재기동 or 웹어플리케이션을 재배포하는 여러 방법중에서 가장 간단한 방법은 아마도 쉘스크립트를 실행하는 방법일 겁니다. 원격 명령어 실행은 Net::SSH를 이용하여 처리합니다. Net::SCP와 유사하니 설명은 생략합니다.

task :restart_was do
  require 'net/ssh' 

  wasserver = Buildr.settings.profile['wasserver']
  Net::SSH.start(wasserver['host'],
                 wasserver['username'],
                 :password => wasserver['password']) do |ssh|
    ssh.exec! wasserver['restart']
  end
end

만약 WAS 재기동 스크립트 실행을 :deploy_webapp 타스크 안에서 처리하고 싶으면 다음처럼 합칠 수 있습니다. (ssh.scp로 쓰인 부분을 주목하세요)

task :deploy_webapp do
  require 'net/ssh'
  require 'net/scp'
  wasserver = Buildr.settings.profile['wasserver']
  Net::SSH.start(wasserver['host'],
                 wasserver['username'],
                 :password => wasserver['password']) do |ssh|    
    ssh.scp.upload! package(:war).name, wasserver['deploy_dir'], :preserve=>true     
    ssh.exec! wasserver['restart']
  end
end

 

'Build&Deploy > Buildr' 카테고리의 다른 글

Buildr : Hudson CI 연계하기  (0) 2009.01.14
Buildr : 설정정보 관리  (0) 2008.12.24
Buildr : 코드분석 리포트 생성  (0) 2008.12.23
Buildr : 빌드결과 패키징  (0) 2008.12.18
Buildr : 아티팩트 다운로드 받기  (0) 2008.12.17
Posted by 에코지오
,