Raspberry pi 무작정 사용해보기

부모님용으로 무작정 구매했다.

SD 카드도 필요해서 마트에 가서 Sandisk 8GB짜리 하나도 집었다. 할인해서 7000원대.

Class도 적혀있지 않고 bulk인 것처럼 생겼는데 그냥 써볼거라 문제되지 않을거라 생각했었다. 하지만 어떤 것들은 사용할 수 없는 것 같기도 하다. (SD Card compatibility list)

1. Raspbian 준비

공식 페이지에서 Raspbian (데비안 계열 raspberry pi용 linux os) 이미지를 다운로드 받은 후 (엄청 느림, http://www.raspberrypi.org/downloads) dd command로 부팅 가능한 SD card를 만들었다. Guide에는 좀 헷갈리게 되어있는데 /dev/disknsn 형태가 아닌 /dev/disk경로를 사용해야 한다.

2. 기타 장치 준비 (PS/2 문제)

Display는 HDMI로만 연결 가능하다. 무선 인터넷은 나중에 설정하면 가능한 것 같기도 한데 Model B의 경우 우선은 유선으로만 가능하다. 키보드와 마우스를 연결해야 하는데, Model B는 USB Port가 2개 뿐이고 PS/2 port는 보이지 않는다. 아쉬운대로 PS/2 to USB 젠더를 이용해서 전원을 연결해봤다. (Raspberry pi는 USB 전원을 연결하자마자 부팅된다. 별도 전원버튼 없음)

boot_log

사진처럼 여느 리눅스처럼 부팅로그가 나타나고 설정 화면으로 이동하는데 로그상으로만 보면 문제점은 없었으나 키보드를 인식하지 못했다. 자료를 찾아보니 PS/2 type 키보드나 마우스의 경우 소모전력 문제로 Raspberry pi에서는 인식이 잘 안되는 것 같다. 특정 젠더나 별도 전원이 있는 hub 같은 걸 사용하면 되는 경우도 있는 것으로 보이나 내가 사용한 젠더로는 인식 불가.

USB용 키보드도 가격이 꽤 나가고 USB port 수도 제한적이라 USB용 RF를 사용하는 키보드/마우스 콤보를 구매했다. (핫트랙스에서 17,900원) 바로 사용가능했음.

3. 인터넷

부팅 / 설정을 끝내고 X window를 띄웠다.

xwindow

X window에 포함된 기본 브라우저 중 하나인 Midori를 실행해서 이메일 확인 및 몇가지 검색을 해봤는데 좀 답답한 감은 있지만 사용못할 수준은 아니다. (SD Card를 class 높은 걸로 바꿔서 다시 해 볼 예정)

4. 기타

최초 부팅 후 설정을 마치지 않더라도 ssh 접속이 가능하다. 접속 계정 정보는 pi / raspberry 이며, sudoer로 등록되어 있는 것 같으니 root 계정을 꼭 사용할 필요는 없다. 또 키보드/마우스, 모니터가 없어도 ssh 접속 상태에서 기본 설정을 진행할 수 있다.

 

(자동화를 위한) Shell script로 MySQL에 insert 하기

빌드와 배포를 자동화하는 작업을 진행하는 도중에 Database에 data를 쓰고 업데이트 하는 기능이 필요하게 되었다. 이 경우 여러가지 방법이 있을 수 있지만 최대한 간단하게, 추가 개발없이 진행하고 싶었다. (Shell script에서)

1. 과거에 사용했던 방법들

간단히 Java로 DB와 connection을 맺고 CRUD를 하는 모듈을 개발해서 사용했던 적이 있다. Jar로 묶어 놓으면 script에서는 jar에 parameter만 몇 개 넘겨서 실행하면 가능했다. 하지만 난 그 당시의 소스를 가지고 있지 않고 간단하더라도 개발을 추가로 하기가 귀찮았다. 시간도 없었고.

두번째로 groovy script를 사용했었다. Groovy 자체가 java와 유사한 부분이 많기 때문에 작성이 어렵지 않았고 그렇게 만들어진 groovy script를 shell에서 호출하는 것도 어렵지는 않다. 하지만 역시 추가로 script를 구현하는게 번거롭고 어딘가에 script를 보관하고 사용해야 한다는게 마음에 걸렸다. 난 단지 하나의 shell script로만 해당 기능을 구현하고 싶었다.

마지막으로 사용해봤던 방법은 REST API를 구현하고 shell script에서는 curl을 이용해 REST API를 호출하는 방법인데, 꽤 괜찮은 방법이 아닌가 생각했었지만 역시 REST API를 구현해야 하는 부담이 있었다. 하지만 대규모 개발이 아니라면 node.js로 충분히 할만하다. (간단하면 개발하는데 그리 오래 걸리지도 않는다)

2. Command line에서 query 실행하기

그동안 사용할 일이 없었기 때문에 MySQL client 실행옵션 중에 -e가 있다는 걸 이번에 알았다. -e 옵션은 뒤에 오는 query 문을 실행해주는 역할을 하는데 이 옵션만 사용하더라도 단 한 줄의 명령으로 원하는 기능을 수행하게 만들 수 있다.

3. Password prompt

한 줄의 명령으로 원하는 기능에 근접했지만 항상 password prompt가 뜨는 문제에 봉착했다. expect를 사용하거나 하면 되겠지만 그것보다 간단한 방법을 원했다. 그리고 찾은게

mysql -uuser_id -ppassword

-p 옵션에 password를 붙여쓰면 따로 묻지 않는다. 그 사이에 공백이 있다면 password prompt를 띄우라는 걸로 인식하고 뒤에 있는 password를 사용하려는 DB schema로 인식한다.

4. Inserted id를 알고 싶어요

또 다른 문제. DB에 insert 하고 특정 작업 이후에 insert된 레코드를 update 해야 했는데 id 이외에 유일한 값을 특정하기가 어려웠다. 강제로라도 유일한 값을 만들수는 있을 것 같았는데 그것을 위해 DB 구조를 변경해야 할 것 같아서 마음에 들지 않았다. 그래서 생각한 방법은 insert 이후에 아래의 query를 바로 실행하는 것이었다.

select last_insert_id();

마지막으로 추가된 id를 알려준다.

5. Shell script에서 text로 된 query 결과를 parsing 해야 하는가?

위의 문제를 해결하니 다른 문제가 등장했다. MySQL client에서 직접 select query를 실행하면 결과를 mysql만의 형태로 돌려준다는 것이었다. Json이나 xml과 같은 정규화된 문자열이 아니라 특수문자로 column의 경계가 그려진 문자열들. 처음엔 이것을 parsing 해야 하나 생각했는데 말도 안되는거라 생각했다. 의미도 없고. 그래서 찾은게 -s와 -N 옵션인데, -s는 silent를 -N은 column name 출력을 하지 않는다. 어차피 마지막에 추가된 id만 알면 되기 때문에 column은 단 하나뿐이고 진정 내가 원하는 것은 그 column의 값일 뿐이다. 두 옵션을 사용해 query를 실행하면 id만 달랑 떨어진다.

6. 결과

mysql -uuser_id -ppassword db_schema -s -N -e “insert_query_with_last_insert_id”

위의 형태로 실행하면 password를 묻지도 않고 insert를 한 후 추가된 id만 받을 수 있다. 단 한줄만으로.

Password가 공개될 여지가 있는데 insert 하려는 값을 parameter로 받는 별도의 script 파일로 만들어서 읽기권한을 제어하는 방법을 사용하는게 어떨까 생각한다. 그게 간단하니까.

Amazon S3에 upload한 파일 접근

Amazon의 S3 서비스를 사용할 때 기본 설정만으로는 upload 한 파일에 대한 접근이 안된다.

Permission 설정이 있길래 건드려 보기도 했는데 permission 만으로는 해결할 수 없었다.

이 부분은 조금 이상하다. 많은 사람들이 permission 설정만으로 접근 권한 제어가 가능할거라 인식할 거라고 보기 때문이다.

또 서비스들이 계속 변경되어서 그런지 검색을 통해 얻는 정보들이 부정확한 것들이 많아서 정리해보기로 했다.

1. 현상

Browser로 간편하게 확인해보기 위해 image를 upload 했다.

그 image의 properties를 확인하면 기본 정보들이 표시되는데 그 중에 link를 열어보면 아래와 같은 화면이 나타난다.

 

XML 형태로 output을 내주고 있는데 AccessDenied로 표시하고 있다.

access_denied

2. Policy 설정

결론부터 얘기하면 모든 resource는 기본적으로 private이라 policy 설정을 해야 접근이 가능한 것으로 보인다. Policy는 (S3에서 얘기하는) bucket 마다 설정이 가능한데, 하위의 디렉토리나 각각의 파일에 대해서는 설정할 수 없다. Bucket의 Properties를 열고 Permission 항목을 확인하면 bucket policy 추가하는 버튼이 있다.

버튼을 눌러보면 텍스트 입력 팝업이 나타나고 하단에 AWS Policy Generator가 보이는데 처음이라 policy의 형식을 잘 모르니 generator를 사용해봤다. Generator를 열어서 필요한 입력 필드에 원하는 정보를 입력한다.

s3_policy

Principal은 policy 적용 대상(사용자)을 의미하는데 익명 사용자에 대해 지정하고 싶다면 *로 입력하고, ARN (Amazon Resource Name)은 표시된 형식대로 입력한다. (arn:aws:s3:::<bucket_name>/<key_name>) Action은 S3에 대한 약간의 지식이 필요한데, 이미지 표시 및 다운로드 (어차피 같은 의미)만 테스트 해볼 것이므로 GetObject를 선택한다. ARN의 key_name은 resource에 대한 key를 의미하는 것으로 보인다. 나의 경우엔 특정 디렉토리에 있는 모든 image를 대상으로 하므로 arn:aws:s3:::my_bucket/sub/dir/* 형태로 입력했다.

모든 필드를 채워서 Generate Policy 버튼을 누르면 S3에서 원하는 형식의 텍스트를 표시해준다. 복사해서 이전의 Bucket Policy Editor에 붙여넣기 한 후 저장하면 적용됨.

3. 결과

아까 전 AccessDenied 응답을 받았던 link를 그대로 열어보면 image가 제대로 browser에서 표시된다. 다른 사용자나 특정 referer에 대한 허가, 거부 등의 세밀한 조정이 필요할 수 있겠다 싶은데 그 부분은 Example Cases for Amazon S3 Bucket Policies를 좀 더 참고해봐야한다.

AChecker – Open Source Contributor가 되다

역시 메일이 왔다. 참 재미있는 세상이 아닌가? 어디에 있는지도 모르고 얼굴도 모르는데 하나의 공통된 주제 때문에 메일을 주고 받을 수 있다니.

1. Merged and beautiful work

메일의 내용은 단순한 메세지였다. Merged #41. 41번째 merge인 것이다. 메일 본문이 어차피 github에 등록된 comment이니 github으로 가본다.

스크린샷 2014-02-10 오후 2.55.17

별 문제가 없었는지 (사실 문제의 여지가 별로 없다. 비즈니스 로직을 수정한 것도 아니고 단순히 버그가 있는 부분을 약간 고친 것에 불과하니까) 내 pull request를 받아줬다. 그래서 merge를 했다. 내가 수정한 부분을 모르는 타인이 받아줬다는 것도 상당히 흥미로운데, beautiful work라고 지나가는 말로라도 한 마디 던져준다. 그래 고맙다. 너네도 beautiful work를 많이 해왔구나. 역시 훈훈하다.

Open source 마다 차이가 있다고 알고 있지만 한두건의 commit 만으로는 contributor로 등록되지 않을 수 있다고 어디선가 봤던 기억이 있는데 혹시나 싶어 contributor list를 열어봤다.

스크린샷 2014-02-10 오후 2.55.46

우오오…젠장. Contributor에 들어있다. 내가 한 건 단지 몇 개 고친 것 뿐인데 기여했다고 인정해주다니. 혹시 pull request 받아들여지기만 하면 자동으로 등록되는거 아닌가? 모르겠지만 여하튼 기쁘다.

2. Open Source 활동은 자격증을 취득하기 위한 과정이 아니다.

AChecker와 관련된 작업을 마치고 생각을 해보았다. 이게 사실 자랑할 거리는 아니지 않는가? 라고. 계속 기록했지만 PHP를 잘 아는 것도 아닌데다가 엄청나게 좋은, 효율적인, 아름다운 코드를 나열한 것도 아니고 많은 부분을 수정하거나 하지 않았기 때문에 내 현재의 능력을 표현하지는 못할거라는 생각이 든다. 그렇기 때문에 ‘나 contributor, 혹은 committer에요’ 라고 내세울만한 그런 일은 아닌 것 같다.

하지만 내가 이런 저런 부분에 관심이 있으며, 흥미와 재미를 느끼고 있다는 점에 대해서는 어필하는 것은 충분히 가능하다고 생각한다. 실제로 업무 이외에 작은 시간을 쪼개서 진행을 했고 이런저런 과정을 거쳐 얻은 성과이기도 하고 그 과정 자체가 충분히 재미있었기 때문에 앞으로도 이런 활동을 지속하게 될 것 같다.

 

Open source 활동은 자격증을 취득하기 위한 과정이 아니다. 그냥 그 과정 자체를 즐기는 과정이다. 정도로 결론내릴 수 있지 않을까.

AChecker에 또 수정할 부분이 보여서 pull request 하러 간다.

AChecker – Open Source 2일차

이전에 pull request 한 것에 대한 메일이 왔다.

1. Commit에 대한 comment

스크린샷 2014-02-10 오후 2.20.31

누군가가 github에서 내가 올려둔 pull request에 comment를 달았는데 같은 내용이 메일로 온 것이다. 내용은 내가 수정할 때 사용한 ENT_IGNORE라는 option (flag)가 보안 이슈가 있는 건데 사용한 특별한 이유가 있냐는 것이었다. 앞서도 언급했지만 난 PHP를 잘 모른다. Flag list들을 문서에서 참고했을 때 있으면 좋을 것이라고 생각했던 것이었는데 그게 보안 이슈가 있는지는 미처 몰랐다.

추가로 comment 단 사람이 관련 문서도 함께 수정해 달라고 요청했다. 문서가 있는지도 몰랐네.

스크린샷 2014-02-10 오후 2.21.09

그리고 contribution 해준게 고맙단다. 사실 나도 고맙다. 내 입장에서는 경험을 쌓는건데 그걸 또 고맙다고 하니까. 뭔가 훈훈하다.

2. 정보 수집

제기된 보안 이슈는 정말 그런 것일까? 문제가 된 ENT_IGNORE에 대한 자료를 찾아보자. 우선 사용한 함수 htmlentities에 대한 문서부터 다시.

스크린샷 2014-02-10 오후 2.30.46

아. 문서(http://kr1.php.net/htmlentities) 자체에도 언급이 되어있다. may have security implications 라고. 왜 미처 저 부분을 못 봤는지…(공식 API 문서에도 언급된 부분이라 신뢰도는 높다고 판단된다) 보안 이슈에 대해 더 자세히 확인하고 싶지만 생략하기로 한다. 기술적인 부분 보다는 open source 활동과 과정에 대한 정리가 지금은 중요하다고 생각하기 때문이다.

3. 작업

어찌되었든 혹시나 해서 넣어둔 flag인데 빼도 문제가 없는지 검토해 보기로 한다. 제거하는 것으로 코드를 수정한 후에 문제가 없는지 테스트를 진행했다. 다행히 ENT_IGNORE를 제거함으로 인해 발생하는 문제는 없었는데 또 다른 문제를 발견할 수 있었다. AChecker가 XML을 생성하면서 정의되지 않은 entity가 포함되는 경우가 있었는데 이에 대한 정의가 없었기 때문에 정상적인 XML로 인식되지 못했다. 그래서 보너스로 그 부분까지 함께 수정. 그리고 commit / push.

4. Pull request에 대한 update

이전에 올린 pull request를 제거하고 다시 등록해야 하나 고민을 했다. 고민을 하면서 최소한 이전에 comment 단 사람에게 댓글은 달아줘야겠다는 생각이 들어서 github에 가보니…

스크린샷 2014-02-10 오후 2.23.51

 

이전의 comment 아래에 내가 fork한 저장소로 push 했던 수정사항이 자동으로 달려있다. Comment에 수정할 파일과 라인넘버까지 명시되어 있었기 때문에 그 부분을 수정한 commit을 자동 감지하는 것인지, 원래 pull request로 등록한 branch에 대한 모든 변경사항들이 pull request가 close 되기 전까지 자동으로 update 되는게 맞는지는 좀 더 살펴봐야 하겠지만 일단 예상했던 자잘한 작업을 안해도 되기 때문에 무척 편리하다는 생각이 들었다.

마지막으로 수정한 부분에 대한 comment를 달아줬다. 영작이 이상하더라도 문제 삼지는 말자. 원래 영어를 잘하지도 못하고 native도 아닌데 우선은 의사전달만 제대로 되면 큰 문제는 없다고 본다. 그래도 영어공부는 계속 해둬야 겠다는 생각은 한다.

 

역시 이 작업까지 마치고 다음을 기다리기로 했다.