$ sudo sysctl -w net.inet.ip.forwarding=1
$ sudo natd -interface en0
$ sudo ipfw add divert natd ip from any to any via en0
Git Submodule Commit
git으로 작업하면서 야심차게 submodule을 도입해봤습니다. 그런데 서브모듈에서 커밋하는 순간부터 막히기 시작하네요.
원칙으로 한다면 submodule을 커밋 & push하고 parent도 commit & push 해 줘야하겠지요. 근데 submodule을 커밋하려면 해당 모듈이 있는 디렉토리로 이동해서 해야합니다.
$ cd submodule && git commit -m 'this is submodule commit message' -a
하나라면 그런데로 할만한데.. 이게 2개 이상이면 좀 짜증이 나기 시작합니다. 그래서 간단하게 쉘 스크립트를 만들어 해봤지요.
녭.. 이런거 해주는 비슷한 것이 있습니다. git foreach 명령이죠.
$ git submodule foreach git commit -m 'this is submodule commit message' -a
그런데 커밋하면 바로 에러가 납니다. 이유는 서브 모듈 중에서 변경되지 않은, 커밋될 필요가 없는 것은 위의 git commit 명령이 오류를 내면서 정지하기 때문이죠. 그래서 모두 커밋하려면 위에서 처럼 분기가 필요한데.. 이를 foreach와 묶는 것을 한 줄로 처리하기 힘들죠..
그리고 된다고 하더리도 아마도 -m 메시지의 공백때문에 제대로 처리가 되지 않을 겁니다.
Update: gist가 좋아보여서 거기다 스크립트 넣어봤습니다. 괜찮네요.
Update: push하는 것도 적용해봤습니다.
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를 사용하는 것을 권장합니다.
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 파일의 사용법에 벗어납니다. 따라서 두번째 방법을 사용하면 됩니다.
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로 등록이 됩니다. 이 옵션은 중복으로 사용 가능합니다.
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에 있는 호스트들이 쫘악~~
끄읏~
매달 자신을 자신의 사무실로 불러 평가하는 것이다.
“어떻게 하고 있는가? 어느 점이 부족한가? 더 잘하기 위해 필요한 도구나 정보, 도움은 있는가?” 다음의 조언을 참고해보자.
- 작은 목표와 큰 목표를 모두 세운다. 그러면 자신을 평가할 시간이 되었을 때 일부 목표는 이미 완성할 수 있다.
- 자신의 일이 모든 측면에서 더 큰 목적과 연관되는 방법을 스스로 이해한다.
- 지나치다 싶을 정도로 정직해진다. 이 연습은 자신의 수행능력을 향상하고 숙련을 달성하는데 도움을 주는 것을 목표로 한다. 그러므로 실수에서 교훈을 배우기는 커녕 대충 얼버무리거나 자신의 실패를 합리화한다면 시간낭비일 따름이다.
출처: 드라이브