포스트

Visual Studio Code 1.99을 Ubuntu 18.04가 설치된 원격 서버에서 사용하기

원래 4월 7일자로 업로드를 하고 싶었는데 어쩌다보니 늦어져서, 그 사이에 Visual Studio Code의 FAQ가 업데이트 됐을 수도 있습니다.

발단

꽤 오랫동안 우분투 버전을 올리지 않은 개발용 서버가 있었다. 최신 버전이 24.04인 걸 생각하면 벌써 6년이 넘게 사용하면서 문제 하나 없었다.

오늘 아침이 되기 전까지는.

평소에 로컬 PC에서 개발용 서버로 Visual Studio Code를 Remote-SSH로 연결해 쓰고 있었는데, 오늘 갑자기 Jupyter extension이 자동으로 업데이트 되더니 나한테 “vscode 버전을 올려라” 라고 하길래 아무 생각없이 vscode의 버전을 1.99로 올렸다.

The remote host may not need VS Code Server’s prerequisites for glibc and libc++ (The remost host does not meet)

대박 갑자기 이런 에러 메시지가 터미널 창에 출력되면서 접속이 안 되는 것이었다. 드디어 올 것이 와버린 것이다.

Linux legacy server support has ended
As of release 1.99, you can no longer connect to these servers. As noted in our 1.97 release, users that require additional time to complete migration to a supported Linux distro can provide custom builds of glibc and libstdc++ as a workaround. More info on this workaround can be found in the FAQ section.

그래서 눈물을 머금고 FAQ로 들어가 시키는대로 하다가 겪은 일련의 고난들을 토대로, 동작하는 방법을 정리해본다. (뒤에선 뭐가 문제였는지도 설명할 예정.)

Crosstool-NG 설치

FAQ에 예시로 나온 명령줄은 전부 다 Docker container 상황을 가정하고 제시하고 있는 내용이라 약간 변형해서 실행했다.

1
2
3
4
5
6
7
8
sudo apt update
sudo apt install -y gcc g++ gperf bison flex texinfo help2man make libncurses5-dev python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip patch rsync meson ninja-build
wget --no-check-certificate http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.26.0.tar.bz2
tar -xvf crosstool-ng-1.26.0.tar.bz2
mv crosstool-ng-1.26.0 /home/judith/tools
cd /home/judith/tools/crosstool-ng-1.26.0
./configure --prefix=/home/judith/tools/crosstool-ng-1.26.0/out && make && make install
export PATH="$PATH:/home/judith/tools/crosstool-ng-1.26.0/out/bin"

이 때 사실 prefix로 소스코드가 있는 루트 폴더의 out 대신에 다른 걸 지정해도 되기는 한데 나중에 crosstool-ng를 빌드할 때 사용할 .config 파일이 소스코드 루트 폴더에 있기 때문에 나는 그냥 저렇게 prefix를 지정했다.

그리고 원래 FAQ에서는 Here are some example configs that you can start with: 라면서 친절하게 config 파일 예제를 몇 개 갖다 줬는데 소용이 없었다. 나중에 설명하겠지만 저 설정들 때문에 하루종일 삽질을 하는 바람에 나는 그냥

  1. .config를 전혀 손대지 않은 상태에서 ct-ng menuconfig를 실행해 GUI (?) 창을 연다.
  2. 몇 가지 옵션만 손댄다
    1. Paths and misc options --->에서 (--passive-ftp --tries=3 -nc --progress=dot:binary) Extra options to wget (NEW) 를 선택해 --no-check-certificate를 추가 (왜냐면 회사에서는 프록시 때문에 그냥은 안 됐기 때문)
    2. Target options --->에서
      1. Target Architecture (alpha) --->로 되어있던 걸 x86으로 바꾼다
      2. Bitness: (32-bit) --->64-bit로 바꾼다
    3. Operating System --->에서
      1. Target OS (bare-metal) --->linux로 바꾼다
      2. Version of linux (6.4) --->4.19.287로 바꾼다 (사실 안 바꿔도 될 거 같긴 한데 혹시 몰라서 vscode 1.99의 요구사항인 4.18만 간신히 넘는 걸로 설정했다.)
    4. C compiler ---> 에서
      1. Version of gcc (13.2.0) --->8.5.0으로 바꾼다 (이것도 사실 안 바꿔도 될 거 같다)
      2. *** Additional supported languages: ***에서 C++도 체크함
  3. 위에서 작업한 설정들을 저장한다
  4. unset LD_LIBRARY_PATH 한 다음 ct-ng build로 빌드한다

저렇게 하면 근데 FAQ에 나와있는 거랑은 다르게 빌드된 sysroot의 라이브러리 폴더 위치가 /home/judith/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot/lib64 처럼 좀 드럽게 잡히기는 하는데 나는 일단 돌아가는 게 최우선이었기 때문에 신경쓸 겨를이 없었다.

※ 만들어진 .config는 필요하면 이걸 갖다 쓰세요.

PatchELF

PatchELF의 경우 crosstool-ng와는 다르게 별도의 설치 과정 없이 이미 빌드된 바이너리만 갖다 쓰면 되서 매우 편했다. 심지어 FAQ에도 나와있듯이 vscode-server가 PatchELF 동작을 지원해주고 있어서 환경변수 3개만 설정해주면 됐다.

다만 습관적으로 .bashrc에 환경변수를 export 해줬는데 remote-ssh를 쓰려면 .profile에 지정해줘야 제대로 반영이 되었다.

1
2
3
4
export PATCHELF_BASE="$HOME/tools/patchelf-0.18.0"
export VSCODE_SERVER_CUSTOM_GLIBC_LINKER="/home/judith/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot/lib64/ld-linux-x86-64.so.2"
export VSCODE_SERVER_CUSTOM_GLIBC_PATH="/home/judith/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot/lib64"
export VSCODE_SERVER_PATCHELF_PATH="$PATCHELF_BASE/bin/patchelf"

저 설정들만 다 해준 다음에 Remote-SSH로 서버에 접속하면 상단에 한 줄짜리 팝업은 뜨지만 문제 없이 접속이 된다. 근데 내가 이렇게 동작하는 거 보겠다고 얼마나 많은 삽질을 했는지 모르겠다.

FAQ의 배신

처음엔 FAQ에서 제공하는 config를 가지고 ct-ng를 빌드하고, 그래도 안 되니 GCC 버전을 살짝만 내려보기도 하고, 그래도 안 되니까 괜히 vscode의 User setting까지 들어간 다음 exec server 체크도 해제해주고 ~/.vscode-server 폴더 밑에 생성되는 거 쭉 쫓아 들어가서 ldd node까지 해서 라이브러리 로드가 어디서 꼬이는지도 확인하고 별 짓을 다 했다.

삽질을 시작하게 된 건 단 한 줄의 로그 메시지 때문이었다.

1
2
3
4
[13:42:08.709] [server] Patching glibc from /home/judith/tools/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib64 with /home/judith/tools/patchelf-0.18.0/bin/patchelf...
[13:42:09.454] [server] Patching linker from /home/judith/tools/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib64/ld-linux-x86-64.so.2 with /home/judith/tools/patchelf-0.18.0/bin/patchelf...
[13:42:10.677] [server] Patching complete.
[13:42:10.678] [server] FATAL: kernel too old

kernel too old라니 대체 이게 무슨 소리인가… Remote-SSH의 OUTPUT을 요리조리 뜯어보는데 아무리 살펴도 Linux kernel 버전이 4.15로 잡히는 것이었다. 그래서 ldd node를 쓰게 된 것. (node는 위에서 대충 언급한 것처럼 일단 vscode의 User settings에서 exec server 체크를 해제해 예전 방식의 실행파일을 개발용 서버에 만들어지게 한 다음 테스트한 것이었다. 위치는 대충 $HOME/.vscode-server/bin/4437686ffebaf200fa4a6e6e67f735f3edf24ada/node)

1
./node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by ./node)

아무래도 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9f93646000) 부분이 마음에 걸리는 게 libc.so.6이 새로 빌드한 crosstool-ng를 잡지 않아서 생긴 문제인 것 같았다. 그런데 하나하나 뜯어보자니 관련된 지식이 충분치 않아서 그냥 .config를 새로 만들어보자고 생각했던 거고 결국 위의 방식으로 해결했다.

참고로 새로 빌드한 sysroot는 까보니 확실히 공식 FAQ에서 제공했던 .config로 빌드한 것과 구성요소의 차이가 있었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
judith@judith-dev:~/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot/lib64$ ll
total 64460
dr-xr-xr-x 2 judith judith     4096  4월  7 17:41 ./
dr-xr-xr-x 7 judith judith     4096  4월  7 17:35 ../
-r-xr-xr-x 1 judith judith  1315384  4월  7 17:35 ld-linux-x86-64.so.2*
-r-xr-xr-x 1 judith judith    20080  4월  7 17:35 libanl.so.1*
-r--r--r-- 1 judith judith   473064  4월  7 17:41 libatomic.a
lrwxrwxrwx 1 judith judith       18  4월  7 17:41 libatomic.so -> libatomic.so.1*
lrwxrwxrwx 1 judith judith       18  4월  7 17:41 libatomic.so.1 -> libatomic.so.1.2.0*
-r-xr-xr-x 1 judith judith   169984  4월  7 17:41 libatomic.so.1.2.0*
-r-xr-xr-x 1 judith judith    31680  4월  7 17:34 libBrokenLocale.so.1*
-r-xr-xr-x 1 judith judith   207408  4월  7 17:34 libc_malloc_debug.so.0*
-r-xr-xr-x 1 judith judith 12938808  4월  7 17:34 libc.so.6*
-r-xr-xr-x 1 judith judith    21432  4월  7 17:34 libdl.so.2*
...

모르긴 몰라도 그냥 심볼릭 링크로 존재한다던가 아예 없으면 안 되는 애들이 있었던 모양.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

Comments powered by Disqus.