Skip to main content

4 posts tagged with "build"

View All Tags

· 7 min read

Jenkins plugin 중 하나를 수정할 일이 있어서 clone 해서 빌드를 해봤는데 테스트에서 실패하는 문제(테스트 코드 상으로는 전혀 문제가 없어보였는데)가 생겨서 plugin 개발 과정 그대로를 진행해봤다.

OS : OS X Yosemite (10.10.3)

IDE : Eclipse Luna

1. settings.xml 준비

Jenkins plugin은 maven으로 dependency 관리 및 빌드를 하도록 되어있는데 라이브러리나 모듈 등을 maven 중앙 저장소 대신 별도 저장소에서 관리하고 있다. 그렇기 때문에 jenkins 저장소들에 대한 경로를 maven이 인식할 수 있어야 하므로 settings.xml 파일에 아래 내용을 추가하라고 가이드하고 있다.

jenkins-plugin-settings

나의 경우에는 별도로 settings.xml 파일을 변경해서 사용하고 있지 않기 때문에 maven 기본 설정을 따라가게 되어있는데 위의 내용을 ~/.m2/settings.xml 파일로 생성해 놓으니다른 maven project들이 의존관계를 갖는 모듈을 찾지 못하는 문제가 있었다. 그래서 별도로 eclipse에서 workspace를 생성해서 그 위치에 settings.xml 파일을 두고 그 workspace에 있는 project들만 위의 settings.xml 내용을 따르도록 조치해두었다. 불편한 점인데 maven의 기본 settings.xml 내용을 안다면 위의 내용만 추가해서 처리할 수 있을 것 같은데 뒤로 미뤄두기로 했다.

2. Plugin 생성 (skeleton)

Plugin tutorial을 따라서 해보니 아래의 command로 새로운 plugin을 생성해줘야 한다.

mvn -U org.jenkins-ci.tools:maven-hpi-plugin:create

그런데 위의 내용대로 하면 maven에 설정된 settings를 따라가게 되기 때문에 jenkins에 대한 의존관계를 찾지 못해 아래와 같은 오류가 발생한다.

jenkins-plugin-create-error

그래서 별도로 생성한 settings.xml을 적용할 수 있게 command를 변경했다.

mvn -s settings.xml -U org.jenkins-ci.tools:maven-hpi-plugin:create

아래 이미지처럼 groupId와 artifactId를 입력하면 skeleton project가 생성된다.

jenkins-plugin-create

3. mvn install (optional)

튜토리얼에는 hpi로 packaging 하기 위해 아래의 command를 사용하라고 되어있다.

mvn install

단순 packaging인데 goal을 install로 하라는게 이상하다. 어차피 IDE에서 드럼과 장구를 칠테니 이 과정은 없어도 될 듯 하다. 그래도 command 변경해서 한 번 해봤다.

mvn -s ../settings.xml install

전형적인 install 처럼 maven 로컬 저장소 경로에 packaging 된 파일들이 생성된다. packaging 과정을 거쳐서 진행되는거니 /project_path/target 에도 hpi가 생성되고 goal을 package로만 지정해도 target에는 hpi가 생성된다.

jenkins-plugin-install

4. mvn hpi:run

Dependency 중에 jenkins war도 있어서 hpi:run을 goal로 지정하면 플러그인이 설치된 상태로 jetty로 jenkins를 실행시켜준다. 이 때 기본 context path는 /jenkins이고 port는 8080

mvn -s ../settings.xml hpi:run

jenkins-plugin-run

5. Project import

Skeleton project는 기본으로는 maven을 사용하고 있으므로 'Existing Maven Project'로 import 해도 된다. 나의 경우엔 특이한 현상이 있어서 eclipse project로 변환해 보기도 했는데 변환할 경우 아래의 command 형태를 사용하도록 튜토리얼에 기술되어 있다.

mvn -DdownloadSources=true -DdownloadJavadocs=true -DoutputDirectory=target/eclipse-classes -Declipse.workspace=/path/to/workspcae eclipse:eclipse eclipse:add-maven-repo

이제 수정하거나 이것저것 만들어서 빌드하고 실행해볼 수 있다.

6. 특이한 현상

경험했던 특이한 현상이 아래의 두가지였다.

(1) Skeleton project를 run 했을 때 configuration에 나타나지 않는 문제

Skeleton project를 그대로 실행하면 원래는 아래 그림처럼 jenkins configuration에 'Hello World Builder' 라는 section이 추가되고 job 설정에서 프랑스어로 인사를 print 할 수 있는 기능을 build에 넣을 수 있게 되어있는데 어느 곳에도 project와 관련된 부분이 나타나지 않는 현상이 있었다.

jenkins-plugin-section

(2) Clone한 project build시 test에서 실패하는 문제

수정하려고 했던 plugin을 clone해서 packaging을 했는데 테스트에서 실패하는 문제가 있었다. 아래 그림처럼 단순한 형태의 테스트 코드였는데 객체가 얻어지지 않는게 테스트 실패의 원인이었다.

jenkins-plugin-test

두 가지 문제를 해결하려고 시도하던 중 eclipse project로 변환하면서 문제들이 저절로 해결되었다. source를 download 하라고 설정되어 있어서 source가 꼭 필요한 무언가가 있어서 해결된 것인가 (그래도 이상하다) 아니면 변환 과정에서 의존성을 가진 일부 모듈을 download 하는 건지 추측을 해봤지만 정확하지는 않다. 아래는 같은 현상을 경험했던 분이 stackoverflow에 올려놓은 글.

http://stackoverflow.com/questions/23002818/jenkins-plugin-shows-on-plugin-page-but-does-not-show-on-configuration-page

· 4 min read

Jenkins는 동일한 job의 동시 실행 갯수를 제한한다.

 

1. Concurrent Build

아무런 조건이 없을 때 Job A가 실행중이라고 가정했을 때, 누군가에 의해서 혹은 remote로 Job A가 trigger 되면 Job A가 Build Queue로 올라간다.

그러므로 concurrent build의 갯수는 2개라고 할 수 있다. (정확히는 executor에 1, queue에 1)

그 이상이 trigger 되는 job은 cancel도 아니고 pending도 아닌 그냥 무시된다.

혹시 로그에는 있을지 모르겠으나 표면으로는 나타나지 않는다.

당연히 build number도 부여되지 않고, history에도 없다.

 

2. 문제

항상 문제가 생긴다. (푸는 게 우리의 일)

동일한 job을 여러개 실행해야 할 상황이 생겼다.

 

3. 상황 설명

Code review 및 기타 이유로 Gerrit을 사용할 예정이다.

Gerrit에서 trigger될 job이 있는데 관리의 편의성까지 고려했을 때 branch 마다 하나의 job을 배치하는게 최선이다.

Gerrit에서 trigger 횟수는 1시간에 수십회 이상이 될텐데 (branch로 나누더라도 마찬가지를 감안해야 함) Jenkins에서 그만큼을 소화할 수가 없다.

결국은 쌓이게 된다는 얘기다.

그리고 문제는 Jenkins에서는 기본적으로 concurrent build 횟수가 2로 제한된다는 사실이다.

나머지는?

결국 버려질 것 같았다.

큰 문제가 발생하는 것이다.

 

4. Hello (real) World

실제로 검토를 했다.

Job 수행시간을 충분히 늘려두고 job을 수없이 trigger 했다. (손으로도, remote로도)

일반적인 job의 경우 결과는 역시 동일했다.

혹시나 싶어 Gerrit에서 trigger 되도록 했다. 여러번.

믿을 수 없게 Build Queue에 쌓여가는 job을 목격할 수 있었다.

 

5. How?

StackOverflow에서 찾아보니 trick이 있었다.

실행될 job의 parameter를 다르게 던지는 것.

필요없어도 아무런 값이나 만들어 던지면 된다고 한다. (StackOverflow 원문 참조)

생각해보니 Gerrit에서 trigger 되는 job은 실제 parameter가 함꼐 오는데 그 값이 모두 다르다.

그래서 보통과는 다른 결과가 온 것이 아닌가 생각된다.

 

6. 회고

가만히 생각해보니 Jenkins의 concurrent build를 제한하는게 어이없지는 않다.

완전히 동일한 내용의 job을 무한정 돌릴 필요가 있을까?

하지만 parameter가 다르다면 job의 이름은 같더라도 다른 내용을 실행하게 될테니 다른 job처럼 인식하는게 올바른 방식일 것 같다.

 

걱정을 하나 덜었다.

· 3 min read

요즘 CI를 하면서 느끼는게 많다. 책에서 그려지는 과정은 상당히 단순한데 사실 형상관리 뿐만 아니라 바뀌어야 하는게 한두가지가 아니라 막상 파헤쳐보니 그리 단순하지 않다.

하지만 재밌는건 어려운 상황이다보니 더 재밌는 아이디어들이 떠오르고, 더 나은 생각과 비젼 같은게 생긴다. 많은 사람들이 흥미도 느끼지 못하고 관련 업체도 국내엔 전무하다시피한 상황(하긴 이것 뿐만이 아니라 SI를 제외하곤 거의 없다) 이지만 그래서 더 연구해볼만한 가치를 느낀다. 예전부터 중요하다 생각했던 부분이기도 하고 나름 흥미를 느껴와서 그런것 같기도 하다.

CI에서 빌드만 자동화를 하고 있지만 자동화의 맹점이기도 한게 사람이 손을 놔버리게 만드는 현상 혹은 습관이라는 생각이 든다. 자동화는 사람을 좀 더 편하게, 조직적으로 효율적으로 운영하고자 하는 수단일 뿐이지 그것 자체가 SW 프로세스 전체의 솔루션이 되어서는 안된다. 관심이 사라지는 순간 시스템 도입 이전으로 돌아가기 쉽고 결국은 비효율적이라며 비싼 돈을 투자한 것들을 버리게 될 가능성이 높다고 본다. 더구나 초기일수록 수작업으로 진행할 때 처럼 관심을...초기 시스템의 오류들은 손으로 잡고 이론과 가설을 수정한 후에 다시 재작업, 그리고 관찰하고 다시 발생하는 문제점들을 해결하는 과정들이 여러차례 반복되어야 나도 그 과정에서 더 배우는게 있겠지. 그나저나 EC2는 어떻게 공부해봐야할까?

· 6 min read

개인적인 사정으로 맥북에서 Android full source를 다운받아서 빌드할 일이 생겼다. Google에서 Mac OS X의 경우에 어떻게 다운로드해서 빌드해야 하는지 설명하고 있지만 그대로 진행했을 경우에 문제점들이 몇가지 있어서 그 부분에 대해 정리해볼까 한다.

 

우선 문제점들이 발생하는 이유는 시간이 흘러서 변경사항이 생겼거나 개인의 환경설정 차이에서 기인하는 것으로 보이는데 일단 내 기준으로 환경을 요약하면 아래와 같다.

OS X 10.6.6, JDK 6 (OS에 기본적으로 탑재된 상태), Macports 설치됨.

Download 참조 페이지 : http://source.android.com/source/download.html

 

#1. 첫번째 문제

위의 페이지대로 진행하다보면 terminal에서 아래와 같은 command를 입력해야 하는 부분이 있다.

$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg

 

설치된 macports로 gmake, libsdl, git-core, gnupg를 내려받아 설치하는 command인데 나의 경우엔 libsdl 설치 도중 오류와 함께 중단되는 경우가 발생했다. Command 포함 오류 메세지는 아래와 같음.

 

$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg
--->  Computing dependencies for gmake
--->  Cleaning gmake
--->  Computing dependencies for libsdl
--->  Dependencies to be installed: xorg-libXext xorg-libX11 xorg-libxcb python27 db46 gdbm openssl zlib readline sqlite3 xorg-libpthread-stubs xorg-xcb-proto libxml2 xorg-util-macros xorg-xcmiscproto xorg-xextproto xorg-xf86bigfontproto xorg-xtrans xorg-libXrandr xorg-randrproto xrender xorg-renderproto
--->  Configuring db46
Error: db46 requires the Java for Mac OS X development headers.
Error: Download the Java Developer Package from: <https://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?bundleID=20719>;
Error: Target org.macports.configure returned: missing Java headers
Error: Failed to install db46
Log for db46 is at: /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_ports_databases_db46/main.log
Error: The following dependencies were not installed: xorg-libXext xorg-libX11 xorg-libxcb python27 db46 gdbm openssl zlib readline sqlite3 xorg-libpthread-stubs xorg-xcb-proto libxml2 xorg-util-macros xorg-xcmiscproto xorg-xextproto xorg-xf86bigfontproto xorg-xtrans xorg-libXrandr xorg-randrproto xrender xorg-renderproto
Error: Status 1 encountered during processing.
To report a bug, see <http://guide.macports.org\/#project.tickets>;

 

문제가 되는건 libsdl 설치할 때 dependency를 가진 다른 모듈들을 설치하는데 db46 이란 녀석이 말썽인거다. 왜 이런 일이 생기는 걸까? 위의 오류 메세지 중에 보면 Download the Java Developer Package from: 어쩌구 하는 부분(빨간색)이 있는데 위의 url로 다운받을 때 문제가 생기는 것으로 보인다. 여기저기 찾아보니 아마 apple 내부에서 어떠한 이유로 url을 변경한 것으로 생각되는데 실제로 위의 url을 입력해보면 redirect 되어 다른 페이지로 이동되는걸 확인할 수 있다. macports는 그 작업을 해주지 않는 것으로 생각되기 때문에 당연히 실패로 끝나는거고.

 

해결책은 무척 간단하다. 위의 문제가 되는 url을 직접 입력해 redirect 되는 페이지에 접근해보면 download 할 수 있게 되어있으니 직접 download 하고 설치하면 끝. 그리고 다시 위의 command를 입력해 진행하면 문제없이 모든게 설치된다.

 

#2. 두번째 문제

또 하나 알게된 사실은 Google에서 제공하는 git repository에서 source를 다운받는데 특정 branch가 사라졌다는 거. Source 다운로드를 위한 모든 잡다구레한게 제대로 설치된 상태에서 repo를 만들기 위해 아래와 같은 command를 입력하라고 google에서 친절하게 알려주고 있다.

$ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake

 

위의 command는 cupcake branch만 다운로드 하기 위해서 repo를 만드는건데, google의 설명을 보면 mainbranch를 원하면 -b 옵션없이 입력하라고 되어있다. 난 gingerbread 까지는 필요없었고 froyo가 적당하다고 판단했기 때문에 -b froyo라고 입력했는데 이런. 오류가 막 생긴다. 역시 찾아보니 froyo라는 branch를 없앤걸로 보이는데 대신 froyo-plus-aosp 라는 이름의 branch 사용은 가능하다. 역시 -b froyo-plus-aosp 로 입력하면 정상적으로 다운로드 가능. 근데 왜 froyo branch를 없앤걸까??

 

 

참조

1. Failed to install db46 (for git-core) : http://comments.gmane.org/gmane.os.apple.macports.user/22266

2. Failed to get froyo : http://groups.google.com/group/android-porting/browse_thread/thread/1dc55cf079291abc/ab1a9ee55681f95f?show_docid=ab1a9ee55681f95f#