chef: role에서 environment에 따라서 run_list 다르게 지정하기

chef를 사용하다보면 environment에 따라서 다른 run_list가 필요한 경우가 있습니다.  이를테면 개발 환경의 서버는 개발자를 위한 편의 기능들을 미리 집어넣는 경우지요. 아마도 개발머신에서는 개발자의 public_key를 모두 등록해서 개발 머신에는 각자의 키로 접속할 수 있고, production에서는 그 기능을 빼는 경우죠.

role에서는 이런 경우를 위해서 env_run_lists를 이용하여 기능을 재공하고 있습니다.

roles/base.rb

name "base"
description "base role for all node"

default_roles = [
	"recipe[chef-client::service]", "recipe[chef-client::config]", "recipe[ntp]",
]

run_list default_roles
env_run_lists	"_default" => default_roles,
				"devel"      => default_roles + ["recipe[my_cookbook::developers_public_keys]"]

굳이 설명 안해도 코드만 보고 다 알겠죠? ㅎㅎ

리눅스 배포판 및 버전 확인하기: lsb_release

스크립트 작업할 때 리눅스 배포판을 확인해서 그에 따라서 작업할 경우가 있습니다. CentOS에는 어쩌구.. Ubuntu에서는 어쩌고...

배포판을 확인할 수 있는 명령은 lsb_release인데 man page에 따르면 아래와 같습니다.

FSG lsb_release v2.0 prints certain LSB (Linux Standard Base) and Distribution information.

여기서 주요하게 필요한 것이 --id(CentOS or Ubuntu), --release(5.8, 12.04)이 두가지 인데, CentOS와 Ubuntu에 약간 차이가 있습니다.

CentOS 5.8에서는

$ lsb_release -i -r -s
CentOS 5.8

Ubuntu 12.04에서는

$ lsb_release -i -r -s
Ubuntu
12.04

이를 스크립트에서 활용할 수 있게 tr 명령과 섞으면 아래와 같이 됩니다.

$ /usr/bin/lsb_release -i -r -s | tr "\\n" " " | sed "s/ *\$//g "
Ubuntu 12.04

이제 이를 이용해서 OS에 따른 대응 코드를 만들면..

#!/bin/bash
function get_dist(){
	/usr/bin/lsb_release -i -r -s | tr "\\n" " " | sed "s/ *\$//g "
}

case $(get_dist()) in
	CentOS*)
		SERVICE=/sbin/service
		SERVICE_NAME=network
		;;
	Ubuntu*)
		SERVICE=/user/sbin/service
		SERVICE_NAME=networking
		;;
	*)
		fatal "Not supported platform"
esac

$SERVICE $SERVICE_NAME restart

끄읏~

나의 메일 박스 레이아웃

요즘 업무용으로 쓰는 메일 박스의 레이아웃은

받은편지함
0. 진행중
  +- 1. 할일
  +- 2. 기다림
1. 진행중인 프로젝트
  +- 1. Project A
2. 팀, 업무
3. 참고
4. 개인
5. 완료된 프로젝트

로.. 구성해서 쓰고 있다. 어디선가 본 메일박스를 이용한 GTD 활용법인데, 생각보다 유용하다.

bash getopts

bash에서는 쉘 스크립트 옵션 처리를 위해서 getopts가 제공됩니다. (주의: getopt 명령과 다름)

#!/bin/bash
while getopts "ha:" opt; do
    case $opt in
        h)
            echo "h option"
            ;;
        a)
            echo "a option=$OPTARG"
            ;;
        \?)
            exit;
            ;;
    esac
done

shift $((OPTIND-1))
echo "나머지 인자: $@"

실행하는 것을 ㅂ면

$ bash opttest.sh -h -a args hello
h option
a option=args
나머지 인자: hello

간단하지요.

getopts는 bash의 builtins으로 간단한 옵션을 처리하는 것이므로 몇가지 제공하지 않는 기능이 있습니다.

  • 긴 옵션을 지원하지 않음: $ opttest.sh --long_options 안됨
  • 옵션이 뒤에 나올 수 없음: $ opttest.sh filename -h 지원하지 않음...

이런 기능을 사용하려면 getopt 명령을 사용하면 되지만... 뭔가 정말로 복잡~ 쉘 스크립트니깐 간단하게 getopts를 사용하는 것을 권장합니다.

참고: http://wiki.bash-hackers.org/howto/getopts_tutorial

dhcp에서 제공하는 dns 서버를 사용하지 않기

dhcp를 사용한다면 특별한 이유가 없는 한 dhcp server에서 제공하는 dns server를 사용합니다. 그런데 이 dns server가 아닌 다른 server를 사용하고자 한다면... 처음으로 /etc/resolv.conf를 직접 수정하는 방법을 생각할 것입니다.

그런데 이 방법의 문제는 /etc/resolv.conf에도 설명이 달린 것 처럼 dhcpclient가 renew 되었을 경우 수정한 내용이 덥혀쓰여진다는 것이지요.

이를 해결하는 방법은 dhclient.conf에 아래와 같이 사용할 dns server를 명시해주면 됩니다.

/etc/dhcp/dhclient.conf:

prepend domain-name-servers <custom-dns-server>;

이렇게 설정된 dns는 /etc/resolv.conf에서 첫번재 entry로 등록이 됩니다. 이 옵션은 중복으로 사용 가능합니다.

dnsmasq는 /etc/hosts를 읽는다. 그리고 no-hosts 옵션

dnsmasq는 dms forwarder로 개인적으로는 아주 간단한 DNS service(내부 개발 서비스)에 주로 사용합니다. 설치하고 /etc/dnsmasq.d/ 파일이 아래처럼 넣으면 되니깐요.

address=/chef.<domain>/192.168.xxx.xxx
address=/dns.<domain>/192.168.xxx.xxx

bind처럼 아주 복잡한 형식의 설정 파일을 건드릴 필요없으니깐요.

위의 예제는 내부 개발 인프라의 dns service를 위해서 저렇게 만들었는데... 하나 문제가 생깁니다. 두번째 호스트는 dns service를 하는 호스트를 표시하는데, 클라이언트에서는 name lookup을 하면 아래처럼 의도하지 않은 결과를 얻게됩니다.

$ nslookup dns.<domain> 192.168.xxx.xxx
Server:         192.168.xxx.xxx
Address:        192.168.xxx.xxx#53

Name:   dns.<domain>
Address: 127.0.0.1

녜.. 의도하지 않게 127.0.0.1로 나오지요.. 이게 뭔지 한참 멍하니 쳐다봤습니다. 해당 호스트로 접속하려니 connnection refused... dnsmasq 설정에는 문제가 없는데 말입니다.

좀 뒤져보니.. dnsmasq는 /etc/hosts 파일을 읽고 그것도 같이 서비스합니다. 그래서 /etc/hosts 파일을 보면

127.0.0.1       localhost
127.0.0.0       dns.<domain> dns

녜.. 여기에서 설정된 호스트 이름이 dnsmasq에 의해서 서비스 되는 것입니다.

해결 방법은 2가지가 있습니다.

첫번째는 /etc/hosts 파일에 ip address 추가하는 겁니다. 127.0.0.1 대신 진짜 ip address를 넣는 것이지요.

127.0.0.1       localhost
192.168.xxx.xxx dns.<domain> dns

두번째 방법은 /etc/dnsmasq.conf에서 no-hosts 옵션을 추가하는 겁니다. no-hosts 옵션의 설명에는 아래처럼 되어 있습니다.

If you don't want dnsmasq to read /etc/hosts, uncomment the follow line.

첫번째 방법은 일반적은 /etc/hosts 파일의 사용법에 벗어납니다. 따라서 두번째 방법을 사용하면 됩니다.

OSX에서 bash auto competition 사용하기..

MacBook을 이제 메인으로 쓰면서 Ubuntu에서 자연스럽게 되된 bash의 자동완성이 안되서 불편한 점이 있습니다. 그래서 간단히 찾아서 설정해봤군요.

먼저 Homebrew를 이용해서 bash completion 패키지를 설치하여 자동완성 지원 파일들을 설치합니다.

$ brew install bash-completion

이제 ~/.bash_profile에 다음 라인을 추가하여 자동완성이 되도록합니다.

if [ -f /usr/local/etc/bash_completion ]; then
        . /usr/local/etc/bash_completion
fi

자.. 다시 쉘을 열고 "ssh "를 입력한 다음에 탭을 두번 누르면 자동완성으로 .ssh/config, .ssh/known_hosts에 있는 호스트들이 쫘악~~

끄읏~

매달 자신을 자신의 사무실로 불러 평가하는 것이다.

"어떻게 하고 있는가? 어느 점이 부족한가? 더 잘하기 위해 필요한 도구나 정보, 도움은 있는가?”
다음의 조언을 참고해보자.

  • 작은 목표와 큰 목표를 모두 세운다. 그러면 자신을 평가할 시간이 되었을 때 일부 목표는 이미 완성할 수 있다.
  • 자신의 일이 모든 측면에서 더 큰 목적과 연관되는 방법을 스스로 이해한다.
  • 지나치다 싶을 정도로 정직해진다. 이 연습은 자신의 수행능력을 향상하고 숙련을 달성하는데 도움을 주는 것을 목표로 한다. 그러므로 실수에서 교훈을 배우기는 커녕 대충 얼버무리거나 자신의 실패를 합리화한다면 시간낭비일 따름이다.

출처: 드라이브

Sublimetext 설정

폰트 설정

Preference > Settings - User

// Settings in here override those in &quot;Default/Preferences.sublime-settings&quot;,
// and are overridden in turn by file type specific settings.
{
	&quot;font_face&quot;: &quot;나눔고딕코딩&quot;,
	&quot;font_size&quot;: 16
}

ref. http://docs.sublimetext.info/en/latest/reference/settings.html

Command line 설정

$ ln -s &quot;/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl&quot; ~/bin/subl

Package 설정

Sublime Package Control 설치한 후에 아래 패키지 설치치

  • Python Auto Complete
  • Django Click
  • Djanero

재밌는 일을 찾아가기…

요즘 인생의 전환기에 있습니다. 녜.. 멀쩡히 다니던 회사를 그만둔 것이죠. 어쨌든 대기업 계열사니깐 누구한테 이야기하면.. 오.. 라는 말이 나오는 사정이긴 합니다만.. 훌훌 털고 나왔습니다.

이유는 하나... 재밌는 일.. 내가 하고 싶은 일 찾아가기...

일이 재미 없었나구요? 물론 재미가 없었다고 말하면 거시기합니다. 일 자체는 참으로 재미있었죠. 하지만 제 자리에 앉아서 뚝딱뚝딱하는 딱 그 시간만 재미있었다고나 할까...

나만이 은둔하던 세상을 벗어나면 담담함.. 그 자체였습니다. 그런데 신기한건 제가 이렇게 은둔하면서 지내는 데도 사람들은 저보고 일을 잘한다고 합니다. 정말로 재밌습니다.

제가 은둔하게 된 계기는 뭐... 간단합니다. 도데체 이놈의 프로젝트가 산으로만 갑니다. 이런 저런 말만 많고, 사공은 없고, 모두들 선장, 항해사가 되려고 합니다. 그러니 이것 저것 깔짝거리다가.. 다시 제자리.. 실제로 되는 일은 없고... 그리고 헤드급이 아닌 동료들과 일을 시작하려면, 다른 누군가가 뭔가 일을 주기만을 기다리고 있습니다.

저를 아는 사람들은 이런 상황에서 제가 어떻게 행동할 것인지 잘 알겁니다.

첫번째.. 이 상황을 몸으로 뚫고 나가자.. 두번째 은둔... 녜.. 전 두번째 은둔을 선택했습니다. 첫번째는 제가 좋아하는 정면돌파의 방법인데, 이건 이렇게 정면 돌파하고 나가고, 싸우다 장렬히 전사해도 적어도 국립묘지에 묻힐 수 있다는 든든한 믿음이 있어야 합니다. 어렸을 때는 앞뒤 안보고 질렀는데.. 이제는 처자식이 딸려서 그러기 힘드네요. 그래서 내 나름대로 프로젝트가 가는 방향을 예상해서 혼자 묵묵히 진행해 나가는 것이죠.. 능력이 안되서 고생 많이 했습니다.

그러다 보니깐 참으로 재밌더군요. 누군가가 말하하는 몰입(flow)에도 자주 갔었습니다. 젊었을 때 느꼈던 그런 열정도 느낄 수 있었습니다.  하지만 이런 은둔의 한계는 혼자만의 것일 뿐이라는 겁니다.

결국.. 이렇게 은둔하는 것도 한계 상황에 다다른 것이죠... 녜... 결론처럼 이제 새로운 것을 찾아 떠나기로 했습니다. 제가 하고 싶은 일을 같이 즐겁게 할 수 있는 조직을 찾아서..

창업하냐고 물어들 봅니다. 아뇨.. 저는 그런 위인이 못됩니다. 제가 회사를 경영하면 망해요. ^^; 이런 이상주의자에다가... 이기주의에 고집불통인 사람은 위로 갈수록 위험한 사람이죠... 그냥 옆에서 지나가면서 툭툭 옳은 말 해주는 것이 제 역할일 겁니다.

^^;

그런데 재밌는 일이 뭘까요? 고민이 많습니다. 아니면 제가 하고 싶은 일이 뭘까?.. 그것도 고민이 많아요.

나름 새워놓은 계획 및 생각도 있지요. 하지만 아직은... 아직은 그런 일들을 실행해 옮길만한 경험이나, 여러 위기 상황에 대처하는 임기응변, 저돌적인 돌파력, 목표를 달성하려는 집요합, 옳은 것을 추구하는 정의감... 등... 이런 생각들을 성공에 이르게하는 여러 부수적인 것들이 너무도 부족하다는 것을 스스로 느끼고 있습니다. 이런 것들을 좀 더 쌓아햐 합니다. 아직 어려요.. ^^;

그래서 고민이 많습니다.

아직 부족한데 이런 부족한 나를 감내해주려는 사람도 있고, 아직 부족한데.. 옆있으며 더 배우고 싶은 사람도 있고.., 아직 부족한데... 더 채워야할 것인데.. 라는 생각이 강합니다.

그냥 정리해 볼랍니다. 재미란...

  • 창조적인, 지식 노동자는 반듯이 일이 재밌어야 한다.
  • 누군가 시켜서 하는 재미는 진정한 재미가 아니다. 재미는 내재된 것이 밖으로 표출되는 것이다. 즉, 자율과 책임의 위임이다.
  • 너무 어려워서도, 너무 쉬워서도 안된다... 즉 구성원들에 대한 세세한 조절이 필요하다.
  • 업무에 재미를 못 느끼는 사람은 없다. 다 느낄 수 있다. 다만 지금까지의 환경때문에 잠시 잊고 살아왔던 것일 뿐이다. 어렵게 보지 말자. 아주 어렸을 때.. 초등학교 들아가기 전에는 세상은 온통 재밌는 것 뿐이었다.
  • 부정적인 것을 보지 말고, 긍정적인 면을 보라.. 재미는 긍정에 있다. 모든 구성원이 모두 수퍼맨이 되길 원하지 말라~
  • 아무리 단순 반복된 일이라도 재미로 바꿀 수 있다. (허클베리 핀의 페인트 칠하기를 보라.. 어렵다면 자포스를 보라..)
  • 서로 협력하여 할 수 있는 조직을 만들어라... 내팀이 아니라 "우리" 팀이다. 내가 담당하는 기능이 아니라.. "우리"가 만들어 가야 하는 기능이다.
  • 학습하며 성장하는 우리가 된다. 처음부터 전문가는 없다. 그래서 모르는, 하지만 해처 나가야할 문제가 생기면 기꺼이 감내한다.
  • 그리고 이 모든 것은 기본적으로 먹고 사는 것에 문제가 없어야 가능하다.

이런 회사(팀, 조직)을 만들어 보는 것이 제 꿈입니다. 그리고 이런 팀, 조직을 서로 조직하여 하나의 공동체로 만들어 보는게 꿈입니다.

그냥.. 이런 저런 생각이 많은 나날들입니다.

ps. 재밌게 살자~