2015년 3월 25일 수요일

[VirtualBox] Host to guest network access

개요
Virtual Box(OSX)에 인스톨된 CentOS에 대해 Network over access하는 방법을 정리

참고자료
http://askubuntu.com/questions/198452/no-host-only-adapter-selected
http://superuser.com/questions/424083/virtualbox-host-ssh-to-guest
https://www.youtube.com/watch?v=Qz_uj_Po2lA

수순

호스트와 게스트를 연결

1. VirtualBox Preference > Network > Host-only Network 에서 호스트 전용 네트워크 어댑터를 1개 추가.
2. VirtualBox VM #n Settings > Network > Adapter 2(or 3 or 4) 에서
Host-only Adapter에서 #1에서 추가된 어댑터를 추가

인터넷 문제를 해결(CentOS7)
* yum이 안되거나 한다면 일단 이를 확인하자

1. 네트워크 어댑터 목록을 확인
...$ nmcli d
DEVICE TYPE STATUS ...
lo loopback unmanaged
enp0s3 ethernet disconnected // <------

2. ipcfg설정
...$ sudo vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
마지막줄의 ONBOOT=yes로 변경설정

3. service network restart
or reboot

4. 설정을 살핌
ip a

5. 인터넷이 되는지 확인
ping 8.8.8.8

호스트에서 게스트로 연결이 되는지 확인

1. ip a
enp0s8정도 되는 기기의 ip를 특정하자. (Host-only adapter로 추정되는 물건)
이번에는 192.168.56.101이라 나왔음

2. 호스트측에서 접근을 확인
ping 192.168.56.101

3. sshd 설정
yum -y install openssh-server openssh-clients
chkconfig sshd on

4. 외부에서 ssh 접근 확인
ssh [username]@192.168.56.101
이후 비번등을 입력해서 접근.

2015년 3월 22일 일요일

[Chef] Solo 입문 메모

개요
Chef Solo입문에 관한 메모

참고자료
http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/cloud/automation

본문

- Chef는 Code를 통한 Infrastructure Provisioning 툴이다

- 코드로 정의된 인프라 구조를 Recipe라 한다

- Chef는 Server, Solo라는 두가지형태가 크게 있는데,
   Server는 복수대의 서버를 유지관리할 수 있는 기능까지 갖추고 있고,
   Solo는 1개 서버의 설정만 해당된다. Solo는 Server의 일부라 할 수 있다.

- Ruby에 기반한다

- 유사 툴로서 Puppet이 대표적이다.

- Facebook의 인프라 유지에 이용되고 있다.

- Idempotent. 멱등성이 보장된 환경. 같은 코드를 몇번 돌리든 코드가 의도하는 바가 유지된다.

Solo 도입순

chef-dk 인스톨

# path는 https://downloads.chef.io/chef-dk/ 에서
wget https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chefdk-0.4.0-1.x86_64.rpm
rpm -ivh chefdk-0.4.0-1.x86_64.rpm 

chef-repo init
# {REPONAME}에 리포지토리의 이름을 지정한다.
chef generate repo {REPONAME}

knife 설정
knife configure

Cookbook 작성
cd {REPONAME}
knife cookbook create {COOKBOOK_NAME} -o cookbooks

recipe json 작성
{PATH-TO-REPO}/localhost.json
{
 "run_list" : [
 "recipe[hello]"
 ]

}

recipe ruby 작성
# solo.rb
file_cache_path "/tmp/chef-solo"

cookbook_path ["/root/{REPONAME}/cookbooks"]

chef 실행
{PATH-TO-REPO}$ sudo chef-solo -c solo.rb -j localhost.json 

Starting Chef Client, version 12.0.3
Compiling Cookbooks...
Converging 1 resources
Recipe: hello::default
  * log[hi there.] action write
  

Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 2.792128558 seconds

패키지의 설정 사례

default.rb에 대해 다음과 같은 예제를 추가해보도록 하자

log "hi there"

execute 'yum update -y' do
  ignore_failure true
end

package "ImageMagick" do
 action :install
end

yum update실시후, 임의의 패키지 매니저로부터 ImageMagick을 인스톨 하는 설정이다.
패키지의 인스톨 자체에 관해서는 특정 패키지 매니저를 지정하지 않는다.

yum이 아닌 apt-get(ubuntu)이나 homebrew(OSX)와 같은 환경이라면 해당 update는 제각각 추가를 해주고, 다만 실패하는 경우를 대비해서 ignore_failure true옵션을 걸어줌으로서 환경에 독립적인 스크립트를 작성할 수 있다.

chef 실행
{PATH-TO-REPO}$ sudo chef-solo -c solo.rb -j localhost.json

Starting Chef Client, version 12.0.3
Compiling Cookbooks...
Converging 3 resources
Recipe: hello::default
  * log[hi there] action write
  
  * execute[yum update -y] action run
    - execute yum update -y
  * yum_package[ImageMagick] action install
    - install version 6.7.8.9-10.15.amzn1 of package ImageMagick

Running handlers:
Running handlers complete

Chef Client finished, 3/3 resources updated in 14.833352817 seconds

2015년 3월 19일 목요일

[Node.js] Bluebird Promise Coroutine

개요
Bluebird Promise에서의 Coroutine사용방법

참조
https://github.com/petkaantonov/bluebird/blob/master/API.md#generators

필수
Node.js >= 0.11.2(현 시점에서 0.12.0이 stable)

수순

실행 커맨드는 이하와 같다. app을 기동할때 다음과 같은 옵션이 필요하다

node --harmony-generators app.js
혹은
node --harmony app.js

mocha 테스트에 있어서도 --harmony옵션을 붙여서 실행할 필요가 있다.

참조 공식 문서로부터 수정한 coroutine 사용예제 (for sails.js)

 /**  
  * CoroutineController  
  *  
  * @description :: Server-side logic for managing coroutines  
  * @help    :: See http://links.sailsjs.org/docs/controllers  
  */  
 var Promise = require("bluebird");  
 function PingPong() {  
 }  
 PingPong.prototype.ping = Promise.coroutine(function* (val,lim,cb) {  
   console.log("Ping?", val);  
   yield Promise.delay(1); // ms  
   if(val < lim) {  
     this.pong(val+1,lim,cb);  
   }  
   else  
   {  
     cb();  
   }  
 });  
 PingPong.prototype.pong = Promise.coroutine(function* (val,lim,cb) {  
   console.log("Pong!", val);  
   yield Promise.delay(1); // ms  
   if(val < lim) {  
     this.ping(val + 1,lim,cb)  
   }  
   else  
   {  
     cb();  
   }  
 });  
 module.exports = {  
   test:function(req,res,next) {  
     var pingpong = new PingPong();  
     pingpong.ping(0,5000,function() {  
       console.log("done");  
       res.json({"message":"done"});  
     });  
   }  
 };  

결과

Ping? 0
Pong! 1
...
Ping? 4996
Pong! 4997
Ping? 4998
Pong! 4999
Ping? 5000
Pong! 5001
done

2015년 3월 12일 목요일

[uFrame 1.5] MVCVM인 이유

개요
uFrame에서 Controller가 ViewModel과 분리되어 있는 이유

본문

ViewModel은 기본적으로 복수개가 생성되는게 전제이므로, Controller (Business Logics)의 경우 구조적으로 ViewModel에 포함될 경우 ViewModel의 갯수만큼 메소드 역시 복제되는 결과를 낳는다. 결과적으로 메모리상에 같은 로직이 대거 복제되어 버리는 결과로 이어지기 때문에, Controller와 ViewModel은 분리되어 각 모델별로 Controller는 1개씩만 작성된다. 그렇기 때문에 Controller의 각 메소드의 제 1 인수는 ViewModel이다 (1:n의 관계이기에)

2015년 3월 10일 화요일

[NGUI] UISprite에 대한 Custom Shader 적용

개요

NGUI에서 UISprite에 대한 Custom Shader의 적용 방법을 정리하고자 한다.
여기서 쉐이더는 일단 desaturate시키는 쉐이더를 예로 들어보도록 하자.

참조

http://www.tasharen.com/forum/index.php?topic=1256.0

설명
우선, NGUI의 Sprite는 1개의 Atlas단위로 쉐이더가 지정되어있다.
참고 링크에서도 이야기가 되고 있지만. 사실 기본적인 의도대로라면 1번의 drawcall에서 shader의 변경이란게 불가능하기 때문에
(정말로? 음... 사실 Sprite에서 임의의 쉐이더를 정의해놓고 drawcall을 쪼개는 한이 있더라도 선택 운용하게 해주면 좋겟다.)
수순대로라면 drawcall을 분리해서 사용해야하는 수순이 된다. 그래서 NGUI에서는 Atlas단위에 있어서 근본적인 설계딴에서 별도의 쉐이더를 분류하고 있지 않다.

자, 우선 여기서 생각해야할 제약조건은

1. Atlas단위로 shader는 고정되어있다.
2. shader를 분리해서 별개의 atlas를 작성해서 이용한다면 일단 렌더링시에 별도의 drawcall로 운용이 된다. 유색 - 무색 - 유색으로 끼게되면 하나의 텍스쳐라도 3번의 드로우콜이 필요하게 될것이다.

그리고 우리가 여기서 생각해야할 부분은

1. 그렇다면 Atlas는 우선적으로 제각각 작성해야할 것이다.
2. 그런데 완전 같은 이미지 소스에 대한 desaturation임에도 불구하고 별도의 texture를 작성할 필요가 있는가?
 -> 흑백 이미지와 컬러 이미지를 따로 작성한다면 유지보수에 있어서도 귀찮아지는 문제점이 발생할것이고, 행여나 실수를 하게되면 리소스가 결여되는 문제가 생길 수 있다.
 -> 심지어 메모리가 2배로 사용된다. 어찌되었든 바람직하진 않다.

여기서 간단히 생각해볼 수 있는것은. NGUI를 확장한다거나 하는 방법이 아닌
1개의 texture를 각각 참조하는 UIAtlas를 2개 작성하는 방법이 그 해결책의 하나가 될 수 있다고 생각한다.

우선 Desaturate를 실시하기 위한 shader에 관해선
아래 링크에 괜찮은 샘플들이 있으니 이 부분은 가져다 쓰도록 하자.

http://forum.unity3d.com/threads/desaturation-grayscale-shader-for-ios.82105/

그리고 문제의 UIAtlas인데 수순은 다음과 같다.

예를들어 UIItem이라는 atlas가 있다고 하자.

그럼 이 atlas의 구성은 다음과 같을 것이다.

UIItem.prefab
UIItem.mat
UIItem.png

우리는 이중에서 UIITem.prefab, UIItem.mat의 2개 파일을 복사할 필요가 있다.
Unity상에서 이 두개의 파일을 선택하여 Ctrl+D / OSX: Command+D 를 눌러서 복제를 하자

아마 UIItem 1과 같은 느낌으로 파일명이 바뀌었을건데, 여기서 양쪽파일명을 Desaturate 아니면 Gray와 같이 1의 부분을 대치하여 파일명을 정리해주자.

이후에 UIItem.prefab의 UIAtlas Component의 Material을 복제된 mat파일을 보도록 다시 링크를 이어주자 (복제했더니 원본을 보고있더라)
그리고 mat쪽에서 상기 링크에 있는 흑백화 쉐이더를 붙여준다.

이후에 UIItem을 이용하고 있던 Sprite에 대해서 이번에 복제 작성한 UIItem???를 연결시켜주면
에디터에서는 여전히 컬러가 들어간 이미지가 표시되지만 게임화면에서는 흑백으로 표시되는것을 알 수 있다.

UIAtlas의 instance자체에서 텍스쳐에 대한 매핑정보를 보존하고 있기 때문에, 한번 갱신을 했다면 이 복제 atlas도 다시 만들어줄 필요가 있다.
이 방법도 다소 귀찮긴 하지만. 적어도 Sprite의 렌더링에 있어서 가장 큰 크기를 차지하는 텍스처가 중복되지 않아도 된다는 장점이 있다.

NGUI에서 공식적으로 서포트 되어주었으면 하지만, 적어도 그때까지는 이런 방법을 강구할 필요가 있을것 같다.
필요에 따라서는 복제 갱신하는 툴이나 배치를 작성해도 되지 않을까