Master Challenge 최종 과제 업무 수행하기 & 우리 팀 첫번째 버그 리포트
오픈소스 컨트리뷰톤 3주차 스프린트 데이에 참여했다.
대다수의 팀원 분들이 온라인으로 참여하고 있지만, 팀원들 얼굴도 눈에 익힐겸 이번에도 스프린트 데이에 정기적으로 참여해 팀에서 진행해야할 과제를 마무리하게 되었다.
(집에서 할 땐 잘 안되는데 오프라인으로 만나면 작업 효율이 극한으로 좋아지는 기적…)
이번 주 활동은 분수령(分水嶺)이다.
과제 수행 진행 상황에 따라 이제 본격적으로 컨트리뷰션 활동을 진행하게 될 멤버로서 합류가 되는지 안되는지를 판단하기 때문이다.
때문에 과제를 좀 더 신중하게 작업하게 되었고, 주중에 해결하지 못했던 일들까지 모두 해결할 수 있게 되었다.
(별도로 멘토님에게 많이 문의하지 않았음에도..후후)
지난 작업 사항 기록 확인하기
오늘 작성하는 글은 팀에서 수행해야하는 과제를 해결한 것으로 총 8가지를 해결했다.
(응? 해놓고 보니 생각보다 많네)
1. 선택 사항이었던 1주차 과제, 10.8.0.0/24 네트워크를 만들고 public network와 연결하는 과정을 cli로 해보기 마무리
사실 순서로 보면 이 과제를 가장 마지막에 수행했다.
오픈스택을 배포하면 왼쪽에 사이드 메뉴가 있고, 거기에 네트워크 관리 메뉴가 있다.
네트워크 관리 사항 중에 네트워크 토폴로지라는 사항이 있고, 그곳으로 들어가면 위와 같은 이미지 구성 형태를 확인할 수 있다.
(참고 : 네트워크 토폴로지란? 컴퓨터 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식이며 네트워크가 어떻게 연결되었는지를 보여주는 구조도라고 생각하면 될 것 같다)
오픈스택을 다루는 과정 자체가 인프라를 구축하는 과정이고, 네트워크 생성 및 할당, 그리고 외부 네트워크와 연결하는 등의 작업이 반드시 필요한 사항이고 Master Challenge 1주차 과제의 선택 사항으로 해당 과제가 주어졌었다.
2주차 과제를 먼저 진행하느라 1주차 과제를 제대로 마무리 못했는데 스프린트 데이인 오늘 작업 효율이 좋아서 2 ~ 3주차 과제를 평소보다 월등하게 높은 생산성으로 해결하고 1주차 과제까지 마무리했다.
(하루 해야할 일을 빨리 마감했을 때, 기분이 정말 좋다 :))
과제 진행 과정은 아래와 같은 절차에 따라 이해하면서 진행했다.
- 1) 먼저 코드로 해결하기 전에 GUI로 네트워크 생성 → 서브넷 생성 → 서브넷 IP 할당 → 라우터 생성 → 라우터를 이용해 Public Network에 서브넷 연결하기
- 2) 위 과정을 코드로 진행하기
GUI로 구성하는 것은 마우스와 그래픽 화면을 이용해 해결하면 되기 때문에 과정을 이해하는데 많은 도움이 되었고, 이걸 코드로 작성하는 과정이 문제였다.
엄청 어렵지는 않았지만, 커맨드에 적용하는 옵션이 자잘하게 있어서 관련한 옵션을 찾는 과정이 시간적인 인내심을 요구했고, 아래와 같이 해결했다.
네트워크 생성하기 : openstack network create <네트워크 이름>
네트워크 서브넷 생성하기 : openstack subnet create — network <네트워크 이름> — subnet-range <서브넷 범위> <서브넷 이름>
네트워크 라우터에 연결하기 : neutron router-interface-add <생성한 라우터 이름> <네트워크 이름>
여기서 사용하고자하는 서브넷 주소는 10.8.0.0/24 였고 나는 서브넷 주소에 이렇게 입력하고 작업했다.
다른 대역대를 사용하고 싶다면 start ~ end로 범위를 지정해서 사용하는 것도 가능하다.
그리고 위 과정을 진행하기 위해서는 별도의 라우터를 먼저 생성해야하는데, 그 작업은 이미 이전에 마무리를 잘 했기 때문에 별도로 라우터를 또 생성해 진행하지는 않았다.
작업 난이도는 낮은데 지난 주에 소스코드 뜯어봐야할 게 워낙 많아서 시간이 많이 지체되었던 것 같다.
2. 2주차 과제 최종 마무리
2주차 과제가 읽을 코드가 많아서 시간을 많이 소모했고, 분석해야하는 코드의 양이 많아서 대략 7일 정도 걸린 것 같다
(2주차 과제 때 마무리를 못해서 3주차 때 마무리하는 슬픔)
과제는 아래의 5개 사항이다.
1) 인자로 입력받은
server list
를 어떻게 구별해내는가?
OpenStack을 사용해서 명령어를 SSH를 사용해서 가상 머신에 원격접속을 하던, 파이참을 사용해서 환경 변수 설정 후 접속을 하던 우리는 커맨드를 통해 오픈스택에 명령어를 줄 수 있다.
그런데 오픈스택에는 굉장히 많은 명령어가 있고, 이를 오픈 스택은 어떻게 읽어들이는가?
먼저 순서대로 OpenStackClient 클론한 폴더의 shell.py라는 파일을 읽어들이면 가장 하단에 메인 함수가 있는 것을 볼 수 있다.
여기서 처음 실행되는 값이 return OpenStackShell().run(argv) 다.
그런데 이 명령어는 shell.py 내부에 있지 않고, osc_lib의 shell.py로 넘어가서 실행이 된다.
그럼 동일해보이는 구조로 ret_val = super(OpenStackShell, self).run(argv) 라는 변수가 설정되어 있는 곳을 볼 수 있고, 마찬가지로 super를 사용해서 자식클래스가 부모 클래스의 어떤 내용을 사용하고 있는지 찾아갈 수 있다.
(pycharm은 특정 클래스 또는 변수에 마우스를 갖다대고 맥에서 cmd 또는 윈도우에서 ctrl을 누른 상태에서 클릭하면 해당 함수로 넘어갈 수 있는 강력한 기능을 지원한다)
여기서 넘어가면 cliff라는 파이썬 모듈의 app.py로 넘어가는 것을 볼 수 있다
(Cliff는 오픈스택을 위한 Command Line Interface Formulation Framework라는 모듈로 커맨드라인을 인식하기 위해 사용하는 모듈이라 보면 된다)
다른 명령어 부분들은 크게 이해하고 넘어갈 필요가 없지만, 앱을 초기화하는 함수가 있는 것을 볼 수 있다.
self.initialize_app(remainder)
이 명령어가 수행하는 역할이 매우 중요한데, 앱을 초기화하면서 다시 python-openstackclient라는 폴더의 shell.py의 함수 2개를 호출한다.
self._load_plugins()
self._load_commands()
이 두 줄을 호출하면, 아래의 코드들이 실행되면서 명령어를 인식할 수 있게 된다.
물론 명령어를 이렇게 인지하는 구조를 만들었지만, 사실 명령어가 실행되는 체계는 더 복잡하고, Command Manager라는 툴이 커맨드를 수행하게끔 실행하는 작업들을 더 진행하는 것으로 알고 있다.
커맨드 라인을 식별하는 과제는 이렇게 찾아낼 수 있었다.
2)
server list
라는 명령어를 처리하는 파일은 무엇인가?
이건 뒤의 과제하고 연결되는데, 다른 명령어 말고 openstack server list 명령어를 수행하면 결과물을 가져오게 수행하는 파일이 있다.
python-openstackclient/compute/v2/server.py 경로이며, 거기서 listserver라는 클래스에서 해당 일을 담당한다.
(찾아내느라 시간은 무진장 걸렸지만, 정답은 깔끔하다…)
3) openstackcli 는 어떻게 nova api 주소를 알아내나요?
OpenStack에서 인스턴스를 생성할 때 도와주는 컴포넌트로 Nova라는 것이 있다.
그런데 이 Nova는 REST API 규칙을 준수하고 있어서 사람들이 찾아보기가 매우 용이한데, 마찬가지로 이 Nova에서 사용하는 API를 CLI가 어떻게 인지하는지를 찾아내는 문제다.
멘티 중 누군가는 api를 호출하는 명령어를 사용할 때 옵션으로 - -debug 를 사용해서 찾았다고 했는데, 나는 코드를 다 뜯어보면서 찾았다.
(삽질은 여전하다)
나는 먼저 Nova API를 호출하는 명령어를 찾아봤고, 이에 따라 2개의 명령어로 API를 볼 수 있다는 것을 알았다.
> openstack catalog list
> openstack endpoint list
그럼 여기서 nova api의 url 경로가 보여서 그 경로에 따라 파일을 따라갔다.
python-openstackclient/identity/v2_0/endpoint.py 파일에서 take_action 함수를 찾아서 엔드포인트 리스트를 가져오는 것을 볼 수 있었다.
4) nova 의 어떤 API를 호출하여 결과를 받아오나요? ( 어떤 URI 를 호출하나요? )
3번을 해결하면 4번이 따라오는데 나는 /compute/v2.1/<instance address>형태로 결과를 받아오는 거라 생각했다.’
(정답이 아닐 수 있다)
5) 결과를 이쁘게 table 형식으로 출력해주는 함수는 무엇일까요?
cliff 모듈에서 formatter라는 폴더가 있고 (차트 형태를 구성해주는 파일) 거기서 table.py가 이 일을 수행해주는 것 같다.
여기서 emit_list라는 함수에 print를 넣어주면 결과에 함께 내 프린트 결과물이 출력되는 것을 알 수 있다.
결과만 보여줘서 그렇지, 찾는데 한참 해멨다.
그래도 파이썬 코드가 질이 좋아서 찾아보면서 파이썬 공부가 되는 것 같아서 매우 좋았다.
3. 3주차 과제 최종 마무리
2번에서 찾아봤던 python-openstackclient/compute/v2/server.py 파일의 하단에 보면 Column을 추가하는 코드가 있고, 여기서 이미 parameter로 프로젝트 ID와 생성 시각을 받아오고 있다.
그걸 문자열로 딕셔너리에 전달만 해주면 끝!
6) 미션 1: openstack server list 의 기본 결과 필드에 “Project ID” 를 추가하기
7) 미션2: openstack server list 의 기본 결과 필드에 “Created At”를 추가하기
4. 방화벽 설정 (누군가 우리의 오픈스택 서버를 해킹했다…!)
여담이지만 누군가 우리의 프로젝트 가상머신 서비스를 해킹했다.
나는 다행히 해킹은 안당했지만, 팀원들 중에 당한 사람이 있었고, 데이터베이스를 지우고 사라졌다.
(별로 중요한 정보가 없어서 정말 다행이라 생각한다)
데이터베이스 로그를 확인해보니 누군가 접속한 기록은 있었고, 아마 방화벽에서 포트를 외부에서 누구나 접속할 수 있게 열어둔 것 때문에 발생한 해킹으로 보였다.
어차피 실습용이고 보안 인증서를 붙일 상황이 아니기 때문에 각자 개인 방화벽을 설정하기로 팀에서 결정을 내렸고, 이에 따라 팀원 개개인이 방화벽을 새롭게 설정했다.
기존에는 인바운드 설정 없이 작업을 했으나 내 컴퓨터의 공인 IP를 원격 IP로 설정하고 작업하게 변경해놨고, 아마 이제 방화벽으로 인해 외부에서 내 컴퓨터가 아닌 다른 사람이 접속하기는 힘들 것으로 보인다.
(참고로 방화벽 자체가 물리적으로 네트워크를 연결하고 끊는 구조를 갖고 있어 Application을 수정할 필요 없이 쉽게 사용할 수 있고, 네트워크에 흘러다니는 모든 패킷을 검사해서 해킹과 같은 외부침입을 근본적으로 막을 수 있다는 장점을 갖고 있다)
아웃바운드는 고칠 필요가 없고 (서버에서 클라이언트 방향으로 나가는 것이기 때문에) 인바운드 규칙을 추가했다.(클라이언트에서 서버로 들어가는 방향, 즉 나만 가상 머신 서버로 접속하게)
자잘하게 오픈소스 컨트리뷰션하면서 배워가는 게 엄청 쌓인다.
5. 후기
Master Challenge가 8월에 종료된다.
솔직히 1 ~ 3주 동안 멘토님들이 내준 과제가 어렵냐고 물어본다면, 지금 관점에서 보건대 절대 어려운 내용들이 아니다.
다만, 처음 다루는 입장에서 파이썬 코드를 쓰더라도 오픈스택 폴더 구조를 익히는 것이 매우 어렵고, Python-OpenStack Client만 쓰더라도 연관된 레포가 2개나 되기 때문에 코드양이 절대 무시하지 못한다.
(눈으로 대충 훑는 코드만 봐도 최소 2 ~ 3천 줄은 되는 것 같다?)
한 달이라는 시간 동안 이걸 익히는 것에 시간을 투자한 게 아깝지 않았고, 이제 본 프로젝트가 시작되면, 남은 기간 동안 나도 게릿(Gerrit)과 StoryBoard를 사용해서 버그 리포트와 커밋 작업을 하게 될 것이다.
이번 주는 팀에서 첫번째 버그 리포트가 커밋된 날이다.
생각보다 작업 속도가 엄청 빨라서 아마 9월 중이면 나도 버그를 꽤 찾아낼 수 있지 않을까하는 생각이 든다.
현업 개발이라는 게 생각보다 엄청 어려운 것이 아니고, 충분히 찾아보면서 해볼 수 있다는 게 굉장히 고무적이다.
추후에 스토리보드와 게릿을 사용한 후기도 정리해야겠다.
이번 오픈소스 컨트리뷰션은 참여하길 정말 잘했다.
Ryan