Your wish is my command

It’s a long journey

Sublimetext 설정

폰트 설정

Preference > Settings - User

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

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

Command line 설정

$ ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" ~/bin/subl

Package 설정

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

  • Python Auto Complete
  • Django Click
  • Djanero

재밌는 일을 찾아가기…

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

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

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

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

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

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

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

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

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

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

^^;

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

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

그래서 고민이 많습니다.

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

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

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

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

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

ps. 재밌게 살자~

도데체 내 Floatingip-list는 뭔고? + Field_specs 사용법

quantum은 nova와는 다르게 사용자를 구별하지 않습니다. 아직 keystone의 인증 기능이 완전하게 통합되지 않는 것이죠. 아마도 grizzly에서 해결할 것 같습니다.

그런데 지금 너무 불편합니다. quantum floatingip-list하면 내가 할당받은 floatingip-list만 나와도 정신없는데, 다른 tenant의 것까지 나온다면 더욱 더 정신없습니다. nova처럼 내것만 나오면 좋을텐데 말입니다.

목마른 사람이 우물판다고 간단하게 스크립트 만들어 봤습니다.

#!/bin/bash
TENANT_ID=$(keystone tenant-list | grep " $OS_TENANT_NAME " | awk '{print $2}')
ARG=$@

if [ ! -z "$TENANT_ID" ]; then
    EXTARG=-tenant_id=${TENANT_ID}

    if [[ ! "$ARG" =~ ' --- ' ]]; then
        EXTARG="- $EXTARG"
    fi
fi

quantum $ARG $EXTARG

사용법은 q.sh로 저장하시고 quantum 명령과 동일하게 쓰면 됩니다. 이제 q.sh로 실행하면 quantum의 대부분의 query 명령이 내가 속한 tenant의 것만 나옵니다. 이제 눈이 좀 정갈해 지는군요.

quantum의 help를 아무리 뒤져봐도 특정 tenant의 목록을 가져오는 것은 없습니다. 유일하게 힌트가 보이는 것 이라고는 filter_specs가 있는데, 여기 키와 값에 뭘 넣어야할지 막막하기도 합니다. 녜 quantum은 이제 folsom 버전에 들어가서 아직 부족한 부분이 많아서 그렇습니다. 당연 문서도 부족합니다(cinder도 아마 그렇지요).

filter_specs에 넣을 수 있는 값들은 리스트된 객체를 show 했을때 보이는 값입니다.

root@:~# quantum net-list
+--------------------------------------+---------+--------------------------------------+
| id                                   | name    | subnets                              |
+--------------------------------------+---------+--------------------------------------+
| 0ded8d5c-9820-4e90-8ca8-97e4a072b2e1 | demo2   | 5d21c90d-7640-4de4-bed7-ce27421851d3 |
| 791d5c88-c437-4f82-97f0-ce435acb2172 | ext_net | c9f2a3cf-2013-4452-b3f5-c778143cc87f |
| d4950d6e-d796-4e30-9fba-d33599ba3644 | admin   | 304f2b2b-6e8f-403c-96b6-0b292007685d |
| e8d18114-540d-4c5e-b2a9-32e4a2e29625 | demo1   | 67b07eb0-235b-4dc4-843c-81e41247e737 |
+--------------------------------------+---------+--------------------------------------+
root@:~# quantum net-show ext_net
+---------------------------+--------------------------------------+
| Field                     | Value                                |
+---------------------------+--------------------------------------+
| admin_state_up            | True                                 |
| id                        | 791d5c88-c437-4f82-97f0-ce435acb2172 |
| name                      | ext_net                              |
| provider:network_type     | gre                                  |
| provider:physical_network |                                      |
| provider:segmentation_id  | 1                                    |
| router:external           | True                                 |
| shared                    | False                                |
| status                    | ACTIVE                               |
| subnets                   | c9f2a3cf-2013-4452-b3f5-c778143cc87f |
| tenant_id                 | e949c418d49649c39005d6dfa7d3ade2     |
+---------------------------+--------------------------------------+

이라고 했을때 여기서 ext_net을 찾는 방법은 아래와 같습니다.

root@:~# quantum net-list -- --name=ext_net
+--------------------------------------+---------+--------------------------------------+
| id                                   | name    | subnets                              |
+--------------------------------------+---------+--------------------------------------+
| 791d5c88-c437-4f82-97f0-ce435acb2172 | ext_net | c9f2a3cf-2013-4452-b3f5-c778143cc87f |
+--------------------------------------+---------+--------------------------------------+
root@:~# quantum net-list -- --router:external=True
+--------------------------------------+---------+--------------------------------------+
| id                                   | name    | subnets                              |
+--------------------------------------+---------+--------------------------------------+
| 791d5c88-c437-4f82-97f0-ce435acb2172 | ext_net | c9f2a3cf-2013-4452-b3f5-c778143cc87f |
+--------------------------------------+---------+--------------------------------------+

하지만.. 이게 절대적인 것은 아니고 대부분 이렇다는 것이네요.. ^^;

Github에 계정이 여러개 있을 때.. Push

github에 계정이 2개 있습니다. 하나는 회사것 하나는 개인것… 물론 public_key도 다르겠지요.. 별 생각없이 사용하면, 개인 레포지트리도 회사의 계정으로 접근을 합니다. 최근까지도 신경안쓰고 있었다가, 개인 레포에 push할 것이 있어서 했는데, 에러가 나더군요.

어떻게 할까.. 고민하다가.. ssh_config를 조금 손보는 것으로 처리했습니다.

Host github.com
User git
HostName github.com
IdentityFile ~/.ssh/company_id_key.rsa

Host whitekid.github.com
User git
HostName github.com
IdentityFile ~/.ssh/personal_key_rsa

위처럼 ~/.ssh/config를 적당히 손봅니다. 이제 ssh github.com하면 첫번째 설정으로 접근하고, ssh whitekid.github.com 하면 두번째 설정으로 접근하게 됩니다.

이렇게 하면 ssh가 구분하여 호스트를 설정하는 것은 되었고 git repository에서는 위의 설정대로 .git/config 파일에서 개인 레포지트르의 호스트 설정을 살짝 바꿔주면 됩니다.

[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = <git@whitekid.github.com>:whitekid/openstack-chef.git

이제는 어디서든 push 해도 햇갈일 일이 없음~

Ec2 Instance Start/ Stop Scripts

클라우드 관련 일을 하니 역시나 사실상 표준인 ec2를 분석할 일이 생겼고, 인스턴스를 만들고 하는 일이 생겼습니다. 콘솔에서 작업하는 것이 너무 귀찮아서 간단하게 모든 region의 instance에 대해서 start/ stop/ status를 보는 스크립트를 만들어봤네요.

물론 이런 일을 해주는 뭔가가 있겠지만, 아주 간단한 일이라 찾는것도 귀찮아서…

#!/bin/bash
export EC2_PRIVATE_KEY=<YOUR EC2 PRIVATE KEY FILE HERE>
export EC2_CERT=<YOUR EC2 CERT FILE HERE>

this=$0
cmd="$1"
shift

function check_expire(){
    f=$1
    EXPIRETIME=$2

    [ ! -f $f ] && return

    NOW=`date +%s` # get current time
    FCTIME=`stat -c %Y ${f}` # get file last modification time
    let "AGE=$NOW-$FCTIME"
    if [[ $AGE -gt $EXPIRETIME ]] ; then
        rm -f $f # this file age is more than the EXPIRETIME above, we can delete it
    fi
}

case "$cmd" in
stop)
    $this | while read region instance etc; do
    ec2-stop-instances -region $region $instance
    done
    ;;

start)
    $this | while read region instance etc; do
    ec2-start-instances -region $region $instance
    done
    ;;

regions)
    let expire_time=60*60*24*7 # expire in a week
    region_cache='/var/tmp/ec2-region-cache'
    check_expire $region_cache $expire_time

    if [ ! -f $region_cache ]; then
        ec2-describe-regions | awk '{print $2}' > $region_cache
    fi

    cat $region_cache
    ;;

    *)
        for region in `$this regions`; do
        ec2-describe-instances -region=$region | grep INSTANCE | awk "{print \"$region \" \$2 \" \" \$4 \" \" \$6}"
        done
    ;;
esac

흠.. ec2 api .. 엄청 느리군요.. ㅡㅡ

Chef: Search Node Role vs Search Node Roles

knife를 이용해 특정 role을 가지는 role을 검색하려면 아래처럼 합니다.

$ knife search node role:openstack-compute

그런데 다른 소스를 뒤져보다 아래와 같이 queury하는 것을 봤습니다.

$ knife search node roles:openstack-compute

뭘까? 하고 그냥 지나치다가 찾아봤죠.. Find Nodes with a Role in the Expanded Run List라고 부르는군요.

간단히 예를 들면

  • nodeA: role-A
  • nodeB: role-B
  • role-A: recipe[A], role[base]
  • role-B: recipe[B], role[base]

이라고 되어있을 경우

$ knife search node role:base

로 할 경우 role에 직접적으로 base가 지정되어 있지 않기 때문에, 검색결과가 없습니다.

$ knife search nodes role:base

로 할 경우는 role-A를 확장하여 role-A, recipe[A], role[base]를 대상으로 찾기 때문에 nodeA, nodeB가 모두 검색이 됩니다.

또한 하나의 side-effect로 role이 expand되는 때는 실제로 chef-client가 실행하면서죠.. 따라서 chef-client가 정상적으로 실행되고 나서야 roles로 검색이 가능합니다. 즉 roles로 검색된 결과는 해당 role로 할당된 노드가 있고, chef-client 정상적으로 cookbook을 실행했다는 의미죠.

OSX의 Resolver의 기능은 Dnsmasq로

dnsmasq는 dns forwarder가 기본입니다. 그리고 또 심플한 dns 기능을 가지고 있습니다. 이 기능을 모르고 이전에 twisted를 이용해서 dns proxy를 만들었지만, dnsmasq를 이용하면 보다 간단하게 설정이 가능하니 설명하지요.

첫번째는 특정 도메인을 특정 네임서버에 보내도록하는 예제입니다.

/etc/dnsmasq.d/company.zone:

server=/dev.company.com/192.168.1.199
server=/myteam.company.com/192.168.1.200

다음 예제는 local이라는 나만의 가상 도메인을 만들고 호스트를 지정하는 방법입니다. /etc/hosts에 설정하는 것과 비슷하죠. /etc/dnsmasq/local.zone:

address=/local-db.local/10.20.1.4
address=/local-[www.local/10.20.1.5][2]

이렇게해서 dnspost는 역사속으로 사라지는군요.

OpenStack은 정말 복잡한 프로젝트다..

문득 얼마나 많은 패키지들이 OpenStack을 위해서 필요한지 단순하게 체크해밨다.

$ apt-get install mysql-server rabbitmq-server \
    keystone glance-api glance-registry \
    nova-api nova-scheduler nova-novncproxy nova-cert nova-consoleauth \
    cinder-api cinder-scheduler cinder-volume \
    nova-compute \
    quantum-server quantum-plugin-openvswitch quantum-plugin-openvswitch-agent quantum-l3-agent quantum-dhcp-agent \
    openstack-dashboard

단순하게 전체 구성하는 패키지를 설치하는 명령을 내리면…

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common augeas-lenses binutils bridge-utils cgroup-lite cinder-common cpp cpp-4.6 cpu-checker curl dbconfig-common dkms dnsmasq-base dnsmasq-utils ebtables
  erlang-asn1 erlang-base erlang-corba erlang-crypto erlang-dev erlang-diameter erlang-docbuilder erlang-edoc erlang-erl-docgen erlang-eunit erlang-ic erlang-inets erlang-inviso erlang-mnesia erlang-nox erlang-odbc
  erlang-os-mon erlang-parsetools erlang-percept erlang-public-key erlang-runtime-tools erlang-snmp erlang-ssh erlang-ssl erlang-syntax-tools erlang-tools erlang-webtool erlang-xmerl fakeroot gawk gcc gcc-4.6 git git-man
  glance-common kpartx kvm kvm-ipxe libaio1 libapache2-mod-wsgi libapparmor1 libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libasound2 libasyncns0 libaugeas0 libavahi-client3 libavahi-common-data libavahi-common3
  libc-dev-bin libc6-dev libcaca0 libconfig-general-perl libcurl3 libdbd-mysql-perl libdbi-perl liberror-perl libevent-2.0-5 libflac8 libgmp10 libgomp1 libhtml-template-perl libibverbs1 libjs-jquery libjs-sphinxdoc
  libjs-underscore libjson0 libltdl7 libmpc2 libmpfr4 libmysqlclient18 libnet-daemon-perl libnetcf1 libnetfilter-conntrack3 libnl-route-3-200 libnspr4 libnss3 libnuma1 libodbc1 libogg0 libplrpc-perl libpulse0 libquadmath0
  librados2 librbd1 librdmacm1 libsctp1 libsdl1.2debian libsgutils2-2 libsigsegv2 libsndfile1 libtidy-0.99-0 libvirt-bin libvirt0 libvorbis0a libvorbisenc2 libxenstore3.0 libxml2-utils libxslt1.1 libyajl1 libyaml-0-2
  linux-libc-dev lksctp-tools make manpages-dev memcached msr-tools mysql-client-5.5 mysql-client-core-5.5 mysql-common mysql-server-5.5 mysql-server-core-5.5 nova-common nova-compute-kvm open-iscsi open-iscsi-utils
  openstack-dashboard-ubuntu-theme openvswitch-common openvswitch-datapath-dkms openvswitch-switch patch python-amqplib python-anyjson python-appconf python-boto python-carrot python-cheetah python-cinder python-cinderclient
  python-cliff python-cloudfiles python-cmd2 python-compressor python-configobj python-crypto python-daemon python-dateutil python-decorator python-dingus python-django python-django-horizon python-eventlet python-feedparser
  python-formencode python-gevent python-gflags python-glance python-glanceclient python-greenlet python-httplib2 python-iso8601 python-jsonschema python-keyring python-keystone python-keystoneclient python-kombu python-ldap
  python-libvirt python-libxml2 python-lockfile python-lxml python-m2crypto python-memcache python-migrate python-mysqldb python-netaddr python-nose python-nova python-novaclient python-openid python-openssl
  python-openstack-auth python-pam python-paramiko python-passlib python-paste python-pastedeploy python-pastescript python-pkg-resources python-prettytable python-pycurl python-pyparsing python-pyudev python-quantum
  python-quantumclient python-requests python-routes python-scgi python-setuptools python-setuptools-git python-simplejson python-sqlalchemy python-sqlalchemy-ext python-stompy python-suds python-swiftclient python-tempita
  python-tz python-utidylib python-warlock python-webob python-xattr python-yaml qemu-common qemu-kvm qemu-utils quantum-common seabios sg3-utils ssl-cert tgt vgabios vlan
Suggested packages:
  www-browser apache2-doc apache2-suexec apache2-suexec-custom augeas-doc binutils-doc python-ceph cpp-doc gcc-4.6-locales virtual-mysql-client mysql-client postgresql-client erlang erlang-manpages erlang-doc xsltproc fop
  erlang-ic-java erlang-observer gcc-multilib autoconf automake1.9 libtool flex bison gdb gcc-doc gcc-4.6-multilib libmudflap0-4.6-dev gcc-4.6-doc libgcc1-dbg libgomp1-dbg libquadmath0-dbg libmudflap0-dbg binutils-gold
  git-daemon-run git-daemon-sysvinit git-doc git-el git-arch git-cvs git-svn git-email git-gui gitk gitweb libasound2-plugins libasound2-python augeas-tools glibc-doc libipc-sharedcache-perl javascript-common libmyodbc
  odbc-postgresql tdsodbc unixodbc-bin pulseaudio policykit-1 pm-utils radvd make-doc libcache-memcached-perl libmemcached libterm-readkey-perl tinyca mailx novnc ethtool diffutils-doc python-amqplib-doc python-markdown
  python-pygments python-crypto-dbg python-crypto-doc python-psycopg2 python-psycopg python-flup python-sqlite geoip-database-contrib python-egenix-mxdatetime python-dns python-gevent-doc python-gevent-dbg python-greenlet-dbg
  python-greenlet-dev python-greenlet-doc python-couchdb python-kombu-doc python-pymongo python-ldap-doc python-lxml-dbg python-mysqldb-dbg ipython python-coverage python-nose-doc python-openssl-doc python-openssl-dbg
  python-pam-dbg python-pastewebkit libapache2-mod-python libapache2-mod-scgi python-pgsql libjs-mochikit python-cherrypy python-distribute python-distribute-doc libcurl4-gnutls-dev python-pycurl-dbg python-gobject python-qt4
  python-pyside.qtcore python-sqlalchemy-doc python-kinterbasdb python-pymssql mol-drivers-macosx openbios-sparc ubuntu-vm-builder uml-utilities openssl-blacklist
The following NEW packages will be installed:
  apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common augeas-lenses binutils bridge-utils cgroup-lite cinder-api cinder-common cinder-scheduler cinder-volume cpp cpp-4.6 cpu-checker curl dbconfig-common dkms
  dnsmasq-base dnsmasq-utils ebtables erlang-asn1 erlang-base erlang-corba erlang-crypto erlang-dev erlang-diameter erlang-docbuilder erlang-edoc erlang-erl-docgen erlang-eunit erlang-ic erlang-inets erlang-inviso erlang-mnesia
  erlang-nox erlang-odbc erlang-os-mon erlang-parsetools erlang-percept erlang-public-key erlang-runtime-tools erlang-snmp erlang-ssh erlang-ssl erlang-syntax-tools erlang-tools erlang-webtool erlang-xmerl fakeroot gawk gcc
  gcc-4.6 git git-man glance-api glance-common glance-registry keystone kpartx kvm kvm-ipxe libaio1 libapache2-mod-wsgi libapparmor1 libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libasound2 libasyncns0 libaugeas0
  libavahi-client3 libavahi-common-data libavahi-common3 libc-dev-bin libc6-dev libcaca0 libconfig-general-perl libcurl3 libdbd-mysql-perl libdbi-perl liberror-perl libevent-2.0-5 libflac8 libgmp10 libgomp1
  libhtml-template-perl libibverbs1 libjs-jquery libjs-sphinxdoc libjs-underscore libjson0 libltdl7 libmpc2 libmpfr4 libmysqlclient18 libnet-daemon-perl libnetcf1 libnetfilter-conntrack3 libnl-route-3-200 libnspr4 libnss3
  libnuma1 libodbc1 libogg0 libplrpc-perl libpulse0 libquadmath0 librados2 librbd1 librdmacm1 libsctp1 libsdl1.2debian libsgutils2-2 libsigsegv2 libsndfile1 libtidy-0.99-0 libvirt-bin libvirt0 libvorbis0a libvorbisenc2
  libxenstore3.0 libxml2-utils libxslt1.1 libyajl1 libyaml-0-2 linux-libc-dev lksctp-tools make manpages-dev memcached msr-tools mysql-client-5.5 mysql-client-core-5.5 mysql-common mysql-server mysql-server-5.5
  mysql-server-core-5.5 nova-api nova-cert nova-common nova-compute nova-compute-kvm nova-consoleauth nova-novncproxy nova-scheduler open-iscsi open-iscsi-utils openstack-dashboard openstack-dashboard-ubuntu-theme
  openvswitch-common openvswitch-datapath-dkms openvswitch-switch patch python-amqplib python-anyjson python-appconf python-boto python-carrot python-cheetah python-cinder python-cinderclient python-cliff python-cloudfiles
  python-cmd2 python-compressor python-configobj python-crypto python-daemon python-dateutil python-decorator python-dingus python-django python-django-horizon python-eventlet python-feedparser python-formencode python-gevent
  python-gflags python-glance python-glanceclient python-greenlet python-httplib2 python-iso8601 python-jsonschema python-keyring python-keystone python-keystoneclient python-kombu python-ldap python-libvirt python-libxml2
  python-lockfile python-lxml python-m2crypto python-memcache python-migrate python-mysqldb python-netaddr python-nose python-nova python-novaclient python-openid python-openssl python-openstack-auth python-pam python-paramiko
  python-passlib python-paste python-pastedeploy python-pastescript python-pkg-resources python-prettytable python-pycurl python-pyparsing python-pyudev python-quantum python-quantumclient python-requests python-routes
  python-scgi python-setuptools python-setuptools-git python-simplejson python-sqlalchemy python-sqlalchemy-ext python-stompy python-suds python-swiftclient python-tempita python-tz python-utidylib python-warlock python-webob
  python-xattr python-yaml qemu-common qemu-kvm qemu-utils quantum-common quantum-dhcp-agent quantum-l3-agent quantum-plugin-openvswitch quantum-plugin-openvswitch-agent quantum-server rabbitmq-server seabios sg3-utils ssl-cert
  tgt vgabios vlan
0 upgraded, 254 newly installed, 0 to remove and 0 not upgraded.
Need to get 124 MB of archives.
After this operation, 422 MB of additional disk space will be used.
Do you want to continue [Y/n]?

254개의 패키지가 필요하다. 물론 모든 full stack을 알아야할 필요는 없겠지만, 어느 정도 그들이 어떤 역할을 하는지는 알아 두는 것이 전체 시스템을 이해하는데 도움이 많이 되겠죠.

완전히 기술 분야가 다른 리눅스 네트워킹부터~ django까지… 후훗… 질릴정도가?

Full Stack

git, unit test, xp, scrum, gerrit, jenkins, chef, ci, cloud…. 프로젝트를 시작할라 치면 실제 삽을 들기도 전에 고려하고 생각하고 해야할 일들이 많다. 물론 여기에 빠진것도 많다.

요즈즘은 특히나 인터넷에 나와있는 유명한 회사, 유명한 오픈소스 플로젝트에서 말하는 best practice들을 보고 있노라면 각 단어 하나가 하나의 책으로 구성해도 부족한 것들인데, 이 모든것을 다 잘 해야만 프로젝트가 잘 될것 같은 생각이 들기도 하다. 실제로 그렇게 가야한다고 이야기도 많이 한다.

이 모든 것을 이미 경험해 본 사람이 있는 경우라면 그나마 좋은 경우겠지만, 구성원들의 지식 수준도 아주 다양하고, 게다가 프로젝트에서 풀어야할 문제 자체도 난감한데, 이를 수행하기 위해 기반을 갖추는 것도 아주 험난한 상황이 되는 것 뭐랄까… 열심히 뭔가를 했지만, 그 것을 사용할 사람에게는 뭔가 보여줄 게 없는 그런 이상한 상황이 오래 지속되는 것 같다.

몇주전에 들었던 야크 세이빙이 떠오르기도 한다….

프로젝트의 비전도 명확하고, 모든 구성원이 동의하고, 아주 열정이 있고, 배우려는 의지도 강하고, 프로젝트 일정도 여유가 있으면 하나씩 파면서 제대로 가겠지만, 그러기도 거시기한게.. 각자의 지식 수준도 다양하고, 그리고 각자에게 뭔가 프로젝트에서 자기 담당이라는 것도 암묵적으로 생기면서, 그 사람이 하겠지 하는 그런 생각도 들기도 하고 말이야… 흠.

내 스타일은 이 모든 것을 갗추어서 제대로 시작하기 보다는 우선은 조그만한 것부터, 작은 성공을 바탕으로 점점 큰 것을 가져나가는 것… 을 추구하고 계속 그렇게 가면서 새로운 것도 쉽게 쉽게 배우고, 그게 왜 필요한 지도 몸으로 느껴가면서 배웠는데 말이다.

만일 저 full stack을 딱 가져다 놓고, 이에 맞춰서 일 해야되.. 라고 한다면, 뭐랄까 답답함이 엄습해올 것 같다. 뭔가 내가 여기서 움직일 공간이 없이 저 틀에 박혀버리는 것 이 아닐까? 하다가 내가 관심있는 분야에 조금 더 뚝딱뚝딱해보려 하지만, 그를 위해서는 더 다른 부가 적인, 배보다 배꼼이 큰.. 그런 일들을 해야하는 상황들이 발생할 것 같다는 느낌도 들고 말이야… 후훗…

이제 혼자가 full stack을 이해하고, 모든 구성원이 케익을 세로롤 자를 수 있으련지.. 뭔가 그렇다…

그냥 넋두리입니다.. :D

ps. 낼은 또 어떤 spike를 할까???