본문 바로가기

오픈소스🥫/SRS

[오픈소스/srs] 1. 오픈소스 도커 디버깅 기본 환경 설정

이런 것에 대한 정보를 담고 있다

  1. 오픈소스 SRS에서 권장하는 방식으로 도커로 디버깅 준비 하는 법
  2. VSCode를 통해 Docker 안에서 디버깅을 하는 법
  3. 오픈소스 기여를 하기위해 이슈를 고르는 법

이런 것에 대한 정보는 담겨있지 않다

  1. vs코드 remote ssh 사용법

1. 오픈소스 SRS 기여를 위한 디버그 환경 설치

개발자가되면 계속해서 하고 싶었던 오픈소스 기여를 하기위해 하고있는 일들을 블로그로 적으려고한다. 일단 프로젝트는 SRS라는 미디어 서버를 선택했다. 미디어 자체에 관심이있고 많이 해보고 싶다 보니 고르게 됐고. 나름 규모있는 프로젝트여서 초보자가 들어가기 위한 가이드같은게 마련되어있어서 고른 것도 있었다. SRS는 프로젝트 적으로 도커에서 실행하는 것을 권장하는 특징이 있었다. 난 처음에 여기부터 막혔었는데, 도커에서 디버그하는법을 몰랐기 때문이다.

일단 한가지 확실한건 기존의 프로젝트를 분석하기 위해서 디버그는 반드시 필요하고 그만큼 어떤 환경에서든 디버그환경을 잘 구성해야한다. 실제로 SRS에서는 디버그를 위한 환경설정 방법을 지원해주고 있었다.

https://github.com/ossrs/dev-docker/tree/ubuntu20

1. SRS 프로젝트 소스를 pull 받기

git clone <https://gitee.com/ossrs/srs.git> srs && cd srs/trunk &&
git remote set-url origin <https://github.com/ossrs/srs.git> && git pull

이 부분은 기존 SRS를 pull 받는다.

2. 도커를 빌드하기

docker run -it --rm -v `pwd`:/srs -w /srs ossrs/srs:dev \\
    bash -c "./configure && make"

srs/trunk 경로를 도커내 /srs 경로와 일치시키겠다는 -v 설정

워킹 디렉토리 설정을 /srs로 하겠다는 -w 설정

도커로의 보이는건 입출력을 가능하게하는 -it와,

그리고 바로 configure 하고 make해서 파일을 만들려고한다.

빌드하려는 저장소는 srs:dev로 디버그를 위해서 dev 브랜치의 파일을 받을 수 있게한다.

binaries, please read <https://ossrs.net/lts/zh-cn/docs/v4/doc/install>
You can:
      ./objs/srs -c conf/srs.conf
                  to start the srs server, with config conf/srs.conf.

3. 도커에서 srs를 실행하기

docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8085:8085 \\
    --env CANDIDATE=$(ifconfig en0 inet| grep 'inet '|awk '{print $2}') -p 8000:8000/udp \\
     -it --rm -v `pwd`:/srs -w /srs ossrs/srs:dev \\
    ./objs/srs -c conf/console.conf

그리고 그 완성된 도커 이미지를 두가지방식으로 실행할 수 있다. 첫번째는 실행을 위해서 사용하는 문구다.

4. 도커에서 srs를 디버그 모드로 실행하기

cd ~/git/srs/trunk &&
docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8085:8085 \\
    --env CANDIDATE=$(ifconfig en0 inet| grep 'inet '|awk '{print $2}') -p 8000:8000/udp \\
    --privileged -it --rm -v `pwd`:/srs -w /srs ossrs/srs:dev \\
    gdb --args ./objs/srs -c conf/console.conf

두 번 째 명령문과 첫 번 째의 차이점은 —previleged라는 설정으로

—previledge로 실행하면 이후에는 실행중인 도커 컨테이너가 필요하고, 그 안에서 디버깅용으로 사용할 IDE와 디버거가 필요하다. 나는 GDB와 VSCODE를 이용해서 디버깅을 한다.

VSCode가 디버그툴을 도커안에서 사용할 수 있게 해주는 키는 remote.ssh 확장 프로그램이고, 루트경로 그 안에서 launch.json을 통해서 설정하고 연다

우리는 디버그 모드로 켜야하기 때문에 밑의 것을 고른다.

만약 설치에 성공했다면 도커 내부에 GDBSERVER를 설치 & 실행하고 GDB 프로세스와 연결하는 과정을 거쳐야한다. 난 그런데 여기서 실패했다. 이 도커의 OS가 지원하는 OS가 아니었고 그러다보니 제대로 프로세스가 연결되지 못했다. 여기서 살짝 당황했지만 그래도 다른 방법을 통해서 디버깅을 구현하려고 했다.

docker run --platform ubuntu\\
-p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8085:8085 \\
--privileged -it --rm -v `pwd`:/srs -w /srs ossrs/srs:dev \\
gdb --args ./objs/srs -c conf/console.conf

근데 이 디버그 자체가

docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8085:8085 \\
--privileged -it --rm -v `pwd`:/srs -w /srs ossrs/srs:dev \\
gdb --args ./objs/srs -c conf/console.conf

gdb —args 자체가  srs 오브젝트를 실행시키고 8080포트가 srs랑 연결돼야하는거 아닌가? 왜 안되고있지 ? 

```
docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8085:8085 \\
    --env CANDIDATE=$(ifconfig en0 inet| grep 'inet '|awk '{print $2}') -p 8000:8000/udp \\
     -it --rm -v `pwd`:/srs -w /srs ossrs/srs:dev \\
    ./objs/srs -c conf/console.conf
```

2. VSCode를 통해 Docker 안에서 디버깅을 하는 법

gdb를 실행시키고 연결하는데 실패했다면 또 다른 방법으로는 VSCode와 Remote ssh를 이용하는 방법이 있다. 다행히 srs는 자신의 소스 내부에 도커 컨테이너를 구축하는 파일이 있기 때문에 이를 조금 변경해서 디버깅을 할 수 있는 환경을 만들려고 했다.

DOCKERFILE

ARG ARCH
ARG IMAGE=ossrs/srs:ubuntu20
FROM ${ARCH}${IMAGE} AS build

ARG CONFARGS
ARG MAKEARGS
ARG INSTALLDEPENDS
ARG BUILDPLATFORM
ARG TARGETPLATFORM
ARG SRS_AUTO_PACKAGER
RUN echo "BUILDPLATFORM: $BUILDPLATFORM, TARGETPLATFORM: $TARGETPLATFORM, PACKAGER: ${#SRS_AUTO_PACKAGER}, CONFARGS: ${CONFARGS}, MAKEARGS: ${MAKEARGS}, INSTALLDEPENDS: ${INSTALLDEPENDS}"

# <https://serverfault.com/questions/949991/how-to-install-tzdata-on-a-ubuntu-docker-image>
ENV DEBIAN_FRONTEND=noninteractive

# To use if in RUN, see <https://github.com/moby/moby/issues/7281#issuecomment-389440503>
# Note that only exists issue like "/bin/sh: 1: [[: not found" for Ubuntu20, no such problem in CentOS7.
SHELL ["/bin/bash", "-c"]

# Install depends tools.
RUN if [[ $INSTALLDEPENDS != 'NO' ]]; then \\
    apt-get update && apt-get install -y gcc make g++ patch unzip perl git libasan5; \\
    fi

# Copy source code to docker.
COPY . /srs
WORKDIR /srs/trunk

# Build and install SRS.
# Note that SRT is enabled by default, so we configure without --srt=on.
# Note that we have copied all files by make install.
RUN ./configure ${CONFARGS} && make ${MAKEARGS} && make install

############################################################
# dist
############################################################
FROM ${ARCH}ubuntu:focal AS dist

ARG BUILDPLATFORM
ARG TARGETPLATFORM
RUN echo "BUILDPLATFORM: $BUILDPLATFORM, TARGETPLATFORM: $TARGETPLATFORM"
RUN apt-get update && apt-get install -y sudo gdb gdbserver
# Expose ports for streaming @see <https://github.com/ossrs/srs#ports>
EXPOSE 1935 1985 8080 5060 9000 8000/udp 10080/udp

# FFMPEG 4.1
COPY --from=build /usr/local/bin/ffmpeg /usr/local/srs/objs/ffmpeg/bin/ffmpeg
# SRS binary, config files and srs-console.
COPY --from=build /usr/local/srs /usr/local/srs

COPY --from=build /srs /srs
# Test the version of binaries.
RUN ldd /usr/local/srs/objs/ffmpeg/bin/ffmpeg && \\
    /usr/local/srs/objs/ffmpeg/bin/ffmpeg -version && \\
    ldd /usr/local/srs/objs/srs && \\
    /usr/local/srs/objs/srs -v

# Default workdir and command.
WORKDIR /usr/local/srs
ENV SRS_DAEMON=off SRS_IN_DOCKER=on
# CMD ["./objs/srs", "-c", "conf/docker.conf"]

추가된 부분

우선 gdb와 gdbserver을 설치한다.

++ RUN apt-get update && apt-get install -y sudo gdb gdbserver

그리고 위에서 만든 실행파일과 연동될 소스 파일들을 가져온다.

++ COPY --from=build /srs /srs

여기서 —from=build는 현재 build와 dist 두단계로 나누어져있는 도커파일에서 dist 단계가 build 단계의 파일에 접근한다는 것을 뜻한다.

CMD ["./objs/srs", "-c", "conf/docker.conf"]

CMD는 도커를 run할 때 바로 실행되는 명령어 같은 것인데. 시작하자마자 실행파일이 실행되면 디버그가 곤란하니 주석처리를한다.

이렇게 하면 준비는 끝났고 이제 vs코드에서 디버그 설정만 마치면 된다

VS코드 디버그 설정하기.

일단 remote-ssh를 이용해 해당 도커 컨테이너 안에 들어가는 것이 필요하다. 그리고 루트 폴더에 .vscode 폴더를 만든다.

그곳에 launch.json파일을 만든다

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "GDB Debug",
      "type": "cppdbg",
      "request": "launch",
      "program": "/usr/local/srs/objs/srs", // 실행 파일 경로
      "args": [
        "-c",
        "/usr/local/srs/conf/docker.conf"
      ], // 필요한 인자
      "stopAtEntry": false,
      "cwd": "/usr/local/srs", // 작업 디렉토리
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "/usr/bin/gdb", // GDB 경로
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "sourceFileMap": {
        "/srs": "${workspaceFolder}/srs"
      }
    }
  ]
}

이 launch.json의 히스토리를 정확히 알고있지는 못하지만, 예상컨데 gdb나 디버깅 툴에 사용되는 쿼리들을 분산한 것에 지나지 않고 vscode가 디버그를 위해서 /.vscode/launch.json을 사용해서 쿼리를 만들어 연결하는 것으로 보인다.

여기서 크게 분석하면 configuration의 program이 실행파일이 있는 경로, arg가 실행파일을 실행하는데 필요한 파일들이라고 생각할 수 있을 것이고, 이후에도 디버거의 경로를 나타내거나 sourceFileMap을 통해서 내 루트파일의 소스파일 경로와 실행되고있는 프로그램에서의 소스경로를 연결해줄 수 있다.

 

기여할 프로젝트 찾기

마지막 여담으로 이제 이런 준비를 마치고 기여할 부분을 찾아내는 작업을 해야한다. 오픈소스에서 기여할 수 있는 부분은 issue 탭에서 찾을 수 있다. 그리고 오픈소스 기여가 활발한 프로젝트 일 수록 초보자가 해결하기 쉬운 이슈들을 모아놓는다. 이것들을 잘 확인해서 개발을 하면 뭔가 월클 같은 오픈소스 개발자가 될 수 있다.