요즘 이상한 모임 슬랙에서 만난 비주류님과 음주를 몇 번 했는데 지난 번에 아마존 Dash를 5개 정도 구입했다는 이야기를 듣고 하나만 달라고 졸랐다가 어제 만난 자리에서 덥썩 건네 주시더라.(thanks a lot!) 물론 비주류님도 아마존 물품을 구입할려는게 아니라 해킹의 목적으로 구입했고, 물론 나도 당연히?
얼마전에 클리앙에 올라온 파이썬 코드로 네트워크 패킷을 캡처해서 활용하는 방법을 그대로 따라 해봤다.
흥미로운 점은 대시 기기에다가 와이파이 패스워드를 어떻게 입력할까? 였는데 스마트폰에 아마존 앱을 설치한 후 대시 디바이스 추가화면에서 스마트폰이 접속된 와이파이 sid의 패스워드를 입력하면 스마트폰의 스피커를 통해서 특정 음을 출력하고 대시에서는 그 음을 마이크센서로 입력받아서 와이파이에 접속하는 방식이였다. 헐헐. 클라우드도 그렇고 사물인터넷 분야에서도 아마존이 제일 무섭다.
구글링 몇 번 해보면 되겠지만 내가 참고한 페이지는 krazyeom’s epilogue라는 블로그였고, 방법도 그대로 따라 했다. 샘플에서는 특정 서비스를 이용해서 Google Drive문서에 데이터를 기록하는 방식이였는데, 나는 사무실에서 점심시간이나 회의시간이 되었을 경우에 버튼을 눌러서 슬랙의 회사 공통 채널에다가 푸시 메시지를 전송하는 걸로 했다. slack webhook을 이용해서 전송하는 방법이라 다른 방법을 쓰진 않고 기존에 리눅스 터미널에서 curl로 slack에 호출하는 스크립트가 있어서 commands를 import해서 바로 curl 명령어를 실행 하였다.
정확히는 모르지만 비주류님한테 설명을 듣기로는 네트워크 패킷을 캡처하는 방식이라 조금은 늦게 메시지가 가지만 이 정도면 훌륭한 IOT 디바이스라 볼 수 있다. 실제 대시에 포함된 센서 가격을 포함하면 3만원 정도 한다고 들었다. 앞으로도 재미있는 장난감들이 많이 나오길 기대해 본다.
얼마전 포스트에서 부산 스타트업 카페 개소소식을 전해 드렸는데 얼마전에 온오프믹스를 통해서 스타트업 미트업이 있다는 이야기를 듣고 다녀왔습니다.
(부산 부전동 송상현 광장에 위치한 스타트업 카페)
어제 얼마전에 새로 생긴 부산 스타트업 카페에서(사)앱센터가 주최하는 스타트업 미트업 행사에 다녀 왔다. 행사 프로그램에 대한 내용은 앱센터 글에 소개되어 있고 연사로 오시는 분중에 유명 스타트업 팟캐스트로 알고 있는 이희우님 빼고는 나머지는 분들은 첨 보는 분들이였다.
후기랄거 까지 없고 간략하게 스타트업 카페와 미트업에 대한 느낌을 정리해 보면 전체적으로 시간이 조금 부족했다는 느낌이 들었다. 평일 저녁 시간이고 연사들이 준비해온 ppt들도 양이 꽤 있다 보니 급하게 마무리되는 경우가 있고 질의응답을 할 시간이 빠져 아쉽웠다. 취재를 온 팀도 있는지 분주하기는 한데 조금은 정신없어 보였다. 그리고 오신 몇몇 분들과 이야기하다 보니 내 예상과는 달리 비IT 스타트업을 하시는 분들이 꽤 있어서 좀 놀라웠다. 요즘 들리는 이야기에 의하면 이런 분들중에서 IT쪽 일을 해보실려는 분들이 꽤 있는 걸로 알고 있다. 여기서 만난 분도 IT쪽은 아닌데 최근에 사물인터넷과 관련한 일을 진행중이라는 이야기를 들었다.
개발자로서 커리어를 처음 시작하고 모 은행 SI프로젝트에 가서 처음 주어졌던 일이 허드슨(지금은 이름이 바껴 Jenkins) 배포 관리였다. 현업이나 PL/PM들이 주로 아침에 개발서버와 스테이징 서버를 통해서 변경된 기능에 대해서 확인하고 이슈를 확인하는 식이였다. 문제는 개발자들이 야근하면서 로컬에서 작성한 코드들을 커밋하고 퇴근하면서 다른 컴포넌트의 의존성 문제로 허드슨의 빌드가 깨져서 개발서버 인스턴스가 부팅이 되질 않아 아침에 확인을 못하는 문제가 생겼다. 그래서 나같은 신입 개발자들이 주로 밤 늦게까지 빌드가 정상적으로 동작하는 지 확인하고 문제가 생기는 경우 직접 수정하거나 개발자한테 연락해서 수정을 하는 식으로, 그야말로 몸빵(?)을 했던 추억이 있다. 그 이후로는 CI툴은 거의 써보질 못했고 대부분 형상관리 시스템이나 개발 프레임워크에서 지원하는 식으로 배포에 대한 이슈가 없었다.
최근에 부산에 몇몇 업체에 개발프로젝트 일을 하거나 주위의 이야기를 들어보면 자동 배포는 개나 줘버려라는 식으로 개발자 로컬 PC에서 파일 단위로 FTP를 통해서 개발서버에 배포하는 경우가 대부분이였다. 일단 개발자의 수가 작은 프로젝트라서 배포에 대한 고민이 크질 않거나 프로젝트마다 개발 환경이 달라져서 CI구성을 하기 힘든 경우가 많아지니 CI나 자동배포를 포기하게 되는 원인이질 않을까 추측해 본다.
내 생각에는 혼자 개발하지 않는 이상, 개발 프로젝트에서는 꼭 CI툴을 이용해서 자동배포하는 환경이 꼭 있어야 본다. 첫번째는 비용(개발자가 하나하나씩 배포할 경우에 시간과 노력)적인 문제이고 두번째는 서버에서 빌드된 파일들의 관리 문제이다. 자바 프로젝트의 경우 개발자 로컬 PC에서 컴파일한 클래스파일을 서버에 올리는 문제인데 개발서버가 리눅스고 자바 환경이 Open JDK를 사용하는 경우 크게 문제가 없을 거 같은데 유닉스 환경에서 벤더사의 JDK를 사용할 경우에는 문제가 달라 진다. 벤더 사의 JDK로 컴파일된 바이트 코드가 런타임 환경과 다를 경우 성능 이슈나 나중에 알 수 없는 오류를 접할 가능성이 있다. 그러므로 꼭 자바 웹 프로젝트일 경우 CI툴을 사용해서 자동배포를 꼭 하자.
준비물(환경)
얼마전에 회사 프로젝트에 배포를 수정한거라 기억이 가물가물하다.
자바 웹 프로젝트이고 프로젝트 루트에 SRC와 WEB(WAS의 도큐먼트 루트와 매칭)이라는 디렉토리가 있고, SRC에 있는 자바 파일을 컴파일되어 개발 서버의 WEB-INF/classes 디렉토리로 배포되어야 한다. 형상관리는 Git을 사용하고 저장소는 Github 유료 플랜으로 비공개 저장소를 사용한다. 개발서버는 데비안 리눅스 버전이고 Open JDK그리고 WAS는 Apache Tomcat이다. Jenkins는 물리적으로 다른 서버에 설치되어 있다. Jenkins 설치 정보는 구글링해 보면 많이 나오니 참고하면 된다.
배포 시나리오는 Git Branch애 개발자가 개발 커밋을 푸시하면 Github 트리거가 발생해서 Jenkins의 웹훅을 호출하고, Jenkins의 스케줄러잡에서 해당 브랜치가 설정되어 있으면 연결된 Git Branch를 체크아웃 받아서 Gradle로 빌드하고 자바 클래스 파일을 War로 묶어서 개발서버에 배포 한다. 그리고 Jenkins 작업 마지막에 원격으로 개발서버에 접속해서 셸스크립트를 실행해서 개발서버 work directory에서 해당 브랜치의 파일들을 pulling해서 WAS의 document ROOT로 복사하는 식이다.
사실 하고 나면 간단한 내용(실제로도 별 내용이 없다)인데 초보자일 경우 아마 환경적인 부분에서 삽질(X) 헤매는 경우가 있을거라 본다. 이런 부분들이나 지적사항은 댓글 남겨 주면 고맙겠다.
Jenkins 설정
1) 젠킨스 Github 플러그인 설치. “Jenkkins 관리”-“플러그인 관리” 화면서 Git/Github 연동 플러그인을 설치 한다. 아래는 실제 설치된 목록이다.
Delivery Pipeline Plugin
Visualisation of Delivery/Build Pipelines, renders pipelines based on upstream/downstream jobs. Full screen view for information radiators.
0.9.5 0.9.4
GIT client plugin
Shared library plugin for other Git related Jenkins plugins.
1.18.0 1.17.1
GIT plugin
This plugin allows use of Git as a build SCM. A recent Git runtime is required (1.7.9 minimum, 1.8.x recommended). Plugin is only tested on official git client. Use exotic installations at your own risks.
2.4.0 2.3.5
GitHub API Plugin
This plugin is a library plugin used by other GitHub related plugins to share the same libraries. This plugin does not have any user visible feature by itself. There's no need to install this plugin manually, although you want to keep it up to date.
1.69 1.68
GitHub plugin
This plugin integrates Jenkins with Github projects.
1.12.0 1.11.3
Groovy
This plugin adds the ability to directly execute Groovy code.
1.27 1.25
Maven Integration plugin
Jenkins plugin for building Maven 2/3 jobs via a special project type.
2.11 2.10
SSH Slaves plugin
This plugin allows you to manage slaves running on \*nix machines over SSH.
1.10 1.9
2) 새로운 스케줄러 잡 등록 젠킨스 첫 화면에서 “새로운 Item”을 클릭해서 새로운 스케줄 잡을 등록하자. 사용하는 Jenkins가 한글화되어 있어서 영어 단어와 다를 수 있으니 유의하길 바란다. 그리고 스케줄러 잡에는 왠만하면 공백을 넣지 않도록 한다. 잡 이름이 시스템상의 경로가 될 수 있기에 편의상 공백없는 이름을 추천 한다.
기본 정보 “Github project”에서 Git Repository 주로 입력
소스코드 관리 항목에서 Git을 선택하고 “Repository URL”과 젠킨스에서 사용할 GitHub 계정을 추가한다. “Branches to build”에서 실제 빌드한 브랜치를 적어 준다. GitFlow를 사용해서 Devel이나 Release브랜치를 기입 한다.
Build항목에서 Invoke Gradle 항목을 선택한다 실행 권한 문제로 Jenkins에서 제공하는 Gradle를 사용했다. “Tasks”는 컴파일 빼곤 다른 게 없어 “build”를 입력하고 “ROOT build script”에서 Gradle 스크립트과 위치한 경로를 기입 한다.
레드햇 리눅스에 yum으로 설치된 젠킨스일 경우 아래 경우에는 gradle스크립트를 위치해 놓는다.
/var/lib/jenkins/jobs/(Jenkins 스케줄러 이름)/workspace
아주 간단한 Gradle 스크립트다. 빌드에서 class파일을 build/bin으로 타겟디렉토리를 지정 한다. 자바 웹 프로젝트이기 때문에 서블릿 jar파일을 빌드 클래스패스에 추가 했다.
} // In this section you declare where to find the dependencies of your project repositories { // Use 'maven central' for resolving your dependencies. // You can declare any Maven/Ivy/file repository here. mavenCentral() }
// In this section you declare the dependencies for your production and test code dependencies { // The production code uses the SLF4J logging API at compile time compile'org.slf4j:slf4j-api:1.7.5' providedCompile 'javax.servlet:servlet-api:2.5' compilefileTree(dir: 'lib', include: '*.jar')
}
다시 Jenkins 스케줄러 화면에서 “빌드 후 조치” 섹션에서 “Send build artifacts over SSH”항목에 개발 서버에 배포할 파일, 여기서는 빌드한 클래스 파일은 build/bin밑에 war파일을 sftp방식으로 배포할려고 한다. 배포한 파일을 ssh로 셸스크립트를 이용해서 archive 해제해서 웹루트에 복사 한다. 항복별로 보면 “Transfers”-“Transfer Set Source files”에서 "**/*.war",입력했고 exec command 에서 셸스크립트의 경로를 지정했다. 참 SSH Server는 미리 Jenkins 전역 설정 화면에서 미리 추가해 놓아야 한다. 나 같은 경우 Jenkins->개발서버로 SSH로 접속시에 공개키로 ssh접속이 가능토록 미리 설정해 놓아서 따로 인증 정보를 추가할 필요가 없다. 이런 방식으로 하길 권한다.
/home/tomcat/deploy/sh/runapp.sh;
나머지 정보는 환경에 맞도록 입력하고 저장 한다. Jenkins에서 “Build Now”를 선택해서 해당 잡의 Console 로그 화면에서 Git까지 체크아웃하고 Gradle까지 실행되었다면 거의 다 한셈이다.
이젠 빌드후에 개발서버에서 실행된 셸스크립트 파일을 간단하게 만들어 봤다. 위에서 설정한 runapp.sh의 내용이다. Git에서 프로젝트 소스를 체크아웃해서 워크디렉토리를 통해 pulling 받은 소스를 웹루트에 복사하는 스크립트이다.
#!/bin/sh cd home/tomcat/webapps/app/ROOT; jar -xf /home/tomcat/webapps/app/ROOT/build/libs/workspace.war rm -rf /home/tomcat/webapps/app/ROOT/build/; # 워킹 디렉토리에서 Git pulling cd /home/tomcat/deploy/(프로젝트 체크아웃 디렉토리)/web; git checkout develop; git pull; # 웹루트로 카피 cp -rf /home/tomcat/deploy/(프로젝트 체크아웃 디렉토리)/web/* /home/tomcat/webapps/app/ROOT/; # tomcat 컨테이너 재기동 /home/tomcat/tomcat7/bin/shutdown.sh; /home/tomcat/tomcat7/bin/startup.sh; # 슬랙 웹훅으로 빌드 성공 메시지를 전송하면 더 좋다. curl -X POST --data-urlencode 'payload={"channel": "#server_room", "username": "bot", "text": ":ok_hand::ok_hand:deploy complete.", "icon_emoji": ":ok_hand:"}' (웹훅 URL) > /dev/null 2>&1
다시 Jenkins로 돌아와서 “Build Now”로 빌드를 실행해서 결과를 확인 한다.
Github 설정
브랜치에 push이벤트가 발생하면 위 Jenkins가 빌드 잡을 실행하도록 서비스 훅 설정이 필요하다. 해당 리파지터리 “Settings”메뉴에서 “Webhooks & Services”메뉴를 선택하고 아래 “Service” 항목에서 Jenkins 정보를 추가 하자.
Github설정까지 끝났으면 브랜치에 소스를 push해서 Jenkins스케줄러 잡이 동작하는 지 확인 해본다. push시에 Jenkins가 동작하지 않는다면 웹 훅 설정이 잘 못된 것이므로 다시 확인해 본다.
사실 내용에 나온 Gradle도 잘 모르는 상태고 Jenkins 설정도 오랫만에 보는거라 삽질을 좀(사실 꽤) 했다. 정리한 내용이 다음 삽질자(?)에게 도움이 되었으면 좋겠다.
맥에서 내가 ‘like’한 텀블러 포스트의 이미지와 동영상만 백업하고 싶은데 구글링해보면 윈도우 프로그램이 몇 있거나, 전체를 백업하는 용도로만 있는 거 같다. 그래서 간단한 node.js로 간단한 스크립트를 만들었다. 개인적으로 node.js를 공부한 지 얼마 안되었으므로 태클달기 있귀업귀.
tumblr의 rest api를 엑세스하기 위해서는 토큰이 필요한 데 먼저 여기에 가서 새로운 앱을 등록해야 한다. 나는 백업 사이트를 유령 앱을 만들었다.
consumer_key, consumer_secret, token, token_secret 4개의 키가 필요한데 token과 token_secet는 텀블러 api 콘솔 메뉴에서 확인할 수 있었다.