이번에는 각종 설정값을 빌드 스크립트에 하드코딩하기 보다는 외부로 빼내어 관리하는 방법을 살펴보겠습니다.
Ant에서는 key=value 형식으로 외부 properties 파일을 이용하고, Maven에서는 사용자홈 경로의 settings.xml 또는 pom.xml 경로의 profiles.xml를 통해 설정정보를 분리합니다. Ant, Maven 모두 스크립트 실행시에 -Dkey=value 형식으로 설정을 입력하는 것도 가능합니다.

Ant와 Maven이 'key=value'라는 1차원적인 프로퍼티 형식으로 설정값을 기록하는 것을 선호한다면, rake나 Buildr은 YAML을 활용하는 2차원적인 트리 형식을 선호합니다. buildfile에서 설정값을 외부로 빼내는 방법은 크게 4가지가 있습니다.

1. 환경변수
스크립트 실행시 key=value  형식으로 입력하면 스크립트에서는 ENV['key']로 값을 받을 수 있습니다. 만약 key에 해당하는 운영체제 환경변수가 있으면 그것을 리턴합니다.

####> buildr upload password=secret

puts ENV['JAVA_HOME']
puts ENV['password']

2. settings.yaml
Buildr을 사용하게 되면 사용자홈/.buildr 디렉토리에 settings.yaml 파일이 생기는데, 여기에 (주로 개발자 개인적인) 설정을 포함할 수 있습니다.

repositories:
  remote :
  - http://www.ibiblio.org/maven2/
  - http://repository.codehaus.org/
  - http://download.java.net/maven/2/

messenger:
  server: jabber.company.com
  usr: notifier@company-jabber.com
  pwd: secret

settings.yaml에 위와 같은 설정이 있으면 스크립트에서는 Buildr.settings.user 속성(Hash)을 통해 값을 읽어옵니다.

puts repositories.remote
puts Buildr.settings.user['messenger']['server']
usr, pwd = Buildr.settings.user['messenger'].values_at('usr', 'pwd')

3. build.yaml
buildfile과 같은 위치의 build.yaml 파일에 (주로 개발자 사이에 공유할) 설정데이터를 넣을 수 있습니다.

artifacts:
  spring: org.springframework:spring:jar:2.0
  log4j: log4j:log4j:jar:1.0
  j2ee: geronimo-spec:geronimo-spec-j2ee:jar:1.4-rc4

jira:
  uri: https://jira.corp.org

build.yaml에 위와 같은 설정이 있다면, 스크립트에서는 Buildr.settings.build 속성(Hash)으로 설정에 접근할 수 있습니다.

compile.with :log4j, :j2ee
puts Buildr.settings.build['jira']['uri']

4. profiles.yaml
buildfile과 같은 위치의 profiles.yaml은 Maven의 profiles.xml과 동일한 역할을 합니다. 보통 빌드환경이 달라지면 다른 설정값이 요구되는데, 이는 프로파일을 통해 관리할 수 있습니다. 즉 프로파일은 빌드환경에 따라 설정값을 다르게 가져가는 것을 말합니다.

development, test, staging, production 등의 빌드환경 중에서 Buildr은 기본적으로 'development' 빌드환경에서 실행됩니다. 빌드 환경은 빌드스크립트 실행시 -e 옵션으로 바꿀 수 있습니다.
빌드 스크립트에서 현재 적용된 빌드환경 값은 Buildr.environment 메소드로 확인 가능합니다.

profiles.yaml에는 이렇게 선택된 빌드환경에 따라 어떤 설정값을 쓸지 YAML 형식으로 적어줍니다.

development:
  db: hsql
  jdbc: hsqldb:mem:devdb
  resource_ext: dev
  wasserver:
    host: 111.111.111.111
    username: testuser
    password: test1234
    deploy_dir: /home/test/deploy/war
    restart: sh restart.sh

production:
  db:oracle
  jdbc: oracle:thin:@bigstrong:1521:mighty
  resource_ext: prod
  wasserver:
    host: 222.222.222.222
    username: realuser
    password: realpass
    deploy_dir: /home/prod/deploy/war
    restart: cd /bea/user_projects/domains/mydomain;./stop.sh;./start.sh

프로파일의 설정값은 빌드 스크립트에서 Buildr.settings.profile 메소드로 읽어옵니다. 

puts Buildr.environment # 현재 적용된 빌드환경
puts Buildr.settings.profile['wasserver']['username'] # 현재 적용된 빌드환경의 설정값
puts Buildr.settings.profiles['production']['wasserver']['username'] # production 환경의 설정 값
Posted by 에코지오
,

우리가 개발하는 어플리케이션은 최종 사용자에게 서비스되기 전에 여러 장소를 거칩니다.

개발자 로컬PC -> (소스저장소) -> 빌드서버(CI서버) -> 개발서버 -> 테스트서버 -> 스테이징서버 -> 운영서버

불행히도 이렇게 거쳐가는 서버에 따라서 환경/정책이 조금씩 다르기 때문에 우리는 개발소스에 포함된 설정값을 다르게 가져가야 합니다. 예전에는 소스가 서버 사이를 옮겨갈 때마다 수작업으로(vi 에디터로) 설정값을 매번 편집을 해주거나, 설정값을 포함한 파일을 빼고(!) 소스를 옮기기도 했습니다. 여러분은 어떤 방법으로 설정값을 다르게 세팅하셨습나요?

여기, 좀더 우아한 방법이 있습니다.

아, 그보다 먼저 설정값을 포함하는 파일을 보통 뭐라고 부르나요? 설정파일 ? 리소스 파일?  뭐라고 부르든 리소스는 주로 xml, properties 로 작성을 하죠. 레일스에서는 yml인가 이런것도 있더군요. 암튼.

그리고 로컬,개발,운영 등 서버의 환경차이에 따라 리소스 파일을 변환하여 개발소스에 포함된 설정을 달리하는 일을 뭐라고 부르나요? 환경맞춤작업? 리소스변환리소스 설정치환? 이런 거에 대한 공식적인 용어를 들은 바가 없어서 일단은 제목에 리소스 설정치환이라고 임의대로 용어를 지었습니다. 혹시 널리 사용되는 용어를 아시는 분은 알려주세요. 언뜻 profile, portable이란 단어가 떠오르기는 합니다만....

아래는 제가 알고 있는 리소스 설정치환 방법 2가지입니다.(리소스 필터링, 리소스 교체 역시 모두 제가 임의로 만든 용어입니다. 더 나은 용어가 있으면 알려주세요.)

1. 리소스 필터링(filtering)
-빌드시에 설정 파일의 내용을 수정하는 방법
-설정값을 하드코딩하지 않고 정해진 형식의 변수로써 설정. 예를 들어 ${jdbc.password}.
-빌드 실행시 설정 파일 내의 변수는 환경에 적합한 설정값으로 치환됨
-환경별 설정값은 빌드스크립트에 보관됨(메이븐의 경우 프로파일 엘리먼트에)

2. 리소스 교체(replacing)
-빌드시에 기준(로컬) 설정 파일을 다른 파일로 교체하는 방법
-설정 파일을 환경별로 분리하여 관리
  (1)환경별로 별도 디렉토리를 만들어 기준 파일과 동일한 파일명으로 관리.
      예를 들어 /web/WEB-INF/web.xml 이 로컬PC용 설정파일이면,
      개발서버용 web.xml은 /conf/dev/web.xml에 두고 관리.
  (2)기준 설정파일과 동일한 경로에, 다른 파일명으로 관리.
      예를 들어 개발서버용 web.xml을 /web/WEB-INF/web.xml.dev 라는 이름으로 관리.
-빌드실행시 환경에 맞는 파일을 골라서 (1)빌드디렉토리로 이동하거나 (2)파일명을 변경하여 기준 설정 파일을 덮어씀

1번 리소스 필터링의 경우 메이븐에서는 Profile 기능과 Resource Filtering 기능을 이용하면 되고, 2번 리소스 교체의 경우 메이븐에서는 Profile 기능과 Ant의 copy 타스크 조합으로 처리할 수 있습니다. 아래는 메이븐에서 2번을 처리한 예제입니다.

... ...
<plugin>
 <artifactId>maven-antrun-plugin</artifactId>
 <executions>
  <execution>
   <id>resource-changing</id>
   <phase>process-resources</phase>
   <goals><goal>run</goal></goals>
   <configuration> <tasks>
          <copy todir="${project.build.outputDirectory}"
                    overwrite="true" preservelastmodified="true" verbose="true">
               <fileset dir="${project.build.outputDirectory}"
                          includes="**/${conf.replace.pattern}" />
                   <mapper type="glob" from="${conf.replace.pattern}" to="*" />
          </copy>
    </tasks></configuration>
  </execution>
...... .......
..... ........
 <profiles>
  <profile>
   <id>env-dev</id>
   <activation>
    <property><name>env</name><value>dev</value></property>
   </activation>
   <properties>
    <conf.replace.pattern>*.dev</conf.replace.pattern>
   </properties>
  </profile>
  <profile>
   <id>env-prod</id>
   <activation>
    <property><name>env</name><value>prod</value></property>
   </activation>
   <properties>
    <conf.replace.pattern>*.prod</conf.replace.pattern>
   </properties>
  </profile>
 </profiles>
Posted by 에코지오
,