PEP 778 – 휠에서 심볼릭 링크 지원
- Author:
- Emma Harper Smith <emma at python.org>
- Sponsor:
- Barry Warsaw <barry at python.org>
- PEP-Delegate:
- Paul Moore <p.f.moore at gmail.com>
- Discussions-To:
- Discourse thread
- Status:
- Deferred
- Type:
- Standards Track
- Topic:
- Packaging
- Requires:
- 777
- Created:
- 18-May-2024
- Post-History:
- 10-Oct-2024
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
현재 휠은 심볼릭 링크를 제대로 처리하지 못하며, 설치할 때 심볼릭 링크를 만드는 대신 콘텐츠를 복사합니다. 휠에서 라이브러리를 올바르게 배포할 수 있도록 심볼릭 링크를 플랫폼에 독립적인 방식으로 처리하는 새로운 LINKS 메타데이터 파일을 제안합니다. 이 명세에는 PEP 777에서 논의된 새로운 휠 주 버전이 필요합니다.
PEP 연기
휠 형식의 주요 변경 사항에 대한 더 나은 호환성 방안이 마련될 때까지 이 PEP는 연기되었습니다. 방해가 되지 않는 방식으로 하위 호환성이 없는 동작을 허용하는 휠 호환성 방안이 마련되면, 이 PEP에서 다음 사항을 다루어야 합니다:
- 이 주제를 POSIX 플랫폼에서 공유 라이브러리에 사용되는 심볼릭 링크로만 다시 한정하고, 아마도 플랫폼 태그와 연결해야 합니까?
- 심볼릭 링크를 아카이브의 파일 속성으로 구체화해야 합니까, 아니면
LINKS파일로 구체화해야 합니까? 이를RECORD에 인코딩할 수 있습니까? - 이 PEP가 더 이상 플랫폼 간에 호환되지 않으므로 PEP 660 편집 가능 설치에 유용하기에는 불충분하다는 점을 명확히 해야 합니다.
- POSIX 플랫폼에서 심볼릭 링크를 사용할 수 없는 경우의 대체 동작을 설명하십시오.
동기
오늘날 휠의 심볼릭 링크는 파일의 복사본으로 생성되는데, 보안상의 이유로 CPython의 zipfile 모듈이 제자리에서 심볼릭 링크 처리를 지원하지 않는다는 점 때문입니다.
이는 휠에서 대규모 컴파일 라이브러리를 제공하려는 프로젝트에 문제를 일으킵니다 . 따라서 프로젝트는 디스크에서 설치 크기를 크게 늘리거나, 심볼릭 링크를 생략하여 일부 다운스트림 사용 사례를 잠재적으로 중단하는 것 중 하나를 선택해야 합니다.
POSIX에서 런타임 사용 또는 빌드 시 링크를 위해 올바르게 로드할 수 있는 라이브러리를 제공하려면, 라이브러리는 POSIX 스타일 로더 및 링커 검색 규칙을 따라야 합니다. 로더가 사용하는 두 가지 주요 파일 이름은 “soname”과 “real name”입니다. “soname”은 libfoo.so.3과 같은 파일이며, 여기서 3은 라이브러리의 인터페이스가 변경될 때 증가하는 숫자입니다. “real name”은 libfoo.so.3.1.4와 같이 이름이 지정된 파일이며, 추가 버전 정보를 통해 로더가 라이브러리의 특정 버전을 찾을 수 있습니다. 마지막으로 라이브러리에 링크할 코드를 컴파일할 때 링커는 libfoo.so와 같이 이름이 지정된 “linker name”을 검색합니다. 자세한 설명은 공유 라이브러리에 관한 이 Linux 문서에서 확인할 수 있습니다. 모든 런타임 및 빌드 시 사용 사례를 완전히 지원하려면 프로젝트에서 세 파일을 모두 제공해야 합니다. 일반적으로 POSIX 플랫폼에서는 심볼릭 링크를 사용하여 이를 처리하므로 라이브러리가 디스크에 세 번 중복되지 않습니다.
Python 패키징으로 돌아가면 numpy, scipy, pyarrow와 같은 바이너리 라이브러리를 제공하는 인기 프로젝트가 많습니다. 또한 다른 휠에는 pytorch 및 jax와 같은 site-packages dlopen 라이브러리도 있습니다. 현재 이러한 프로젝트는 휠에 있는 단일 라이브러리에 의존하지만, “real name” 라이브러리 버전을 사용할 수 있는 시스템 라이브러리가 있으면 링커가 잘못된 라이브러리를 찾을 수 있습니다.
휠의 심볼릭 링크를 사용하면 사용자의 site-packages 디렉터리에 심볼릭 링크를 배치하는 것만으로 더 간단한 편집 가능 설치를 구현할 수 있다는 잠재적인 이점도 있지만, 이 PEP에서는 이를 향후 PEP에서 살펴볼 미해결 문제로 남겨 둡니다.
근거
POSIX에서 로딩 및 라이브러리 링크에 사용되는 라이브러리의 세 가지 주요 명명 방식을 지원하기 위해 Python 휠에 심볼릭 링크 지원을 추가할 것을 제안합니다. 생성된 심볼릭 링크를 추적하고 POSIX 심볼릭 링크를 직접 지원하지 않을 수 있는 다른 플랫폼도 잠재적으로 지원할 수 있도록, METADATA, RECORD 및 기타 메타데이터 파일과 함께 .dist-info 디렉터리에 존재하는 새로운 휠 메타데이터 파일 LINKS를 사용할 것을 제안합니다.
LINKS 파일을 사용하면 심볼릭 링크와 유사한 사용을 여러 플랫폼에서 더 많이 활용할 수 있습니다. Windows에서는 심볼릭 링크를 만들 수 있도록 사용자에게 허용하는 그룹 정책 (예: 개발자 모드 활성화) 또는 관리자 권한이 필요합니다. 따라서 일부 사용자 시스템에서는 심볼릭 링크가 지원되지 않을 수 있습니다. LINKS 파일을 사용하면 설치 프로그램이 심볼릭 링크를 처리할 때 다른 방법을 사용할 수 있으며, 그렇지 않으면 설치에 실패해야 하는 경우에도 Windows의 접합점과 같은 방법을 잠재적으로 사용할 수 있습니다.
이 PEP에서는 업데이트된 wheel을 설치할 때 설치 프로그램이 수행해야 하는 검사도 설명합니다. 이러한 검사는 wheel에서 심볼릭 링크를 설치하도록 허용할 때 발생하는 보안 위험을 처리하기 위해 존재합니다. 이러한 검사가 중요한 이유에 대한 자세한 내용은 보안 관련 영향을 참조하십시오.
사양
Wheel 주 버전 증가
이 PEP에서는 휠 주 버전 증가가 필요하므로, Wheel-Version은 LINKS로 생성된 휠에서 적어도 버전 2.0이어야 반드시 합니다. 이는 이전 설치 프로그램이 심볼릭 링크 설치에 조용히 실패하여 사용자 환경을 손상시키지 않도록 하기 위한 것입니다. 자세한 내용은 PEP 777을 참조하십시오.
새 LINKS 메타데이터 파일
플랫폼 간 심볼릭 링크를 지원하기 위해 이 PEP에서는 새로운 wheel 메타데이터 파일인 LINKS를 도입합니다. 다음은 LINKS 파일의 예입니다.:
my_package/libfoo.so.3.1.4,my_package/libfoo.so.3
my_package/libfoo.so.3,my_package/libfoo.so
위에서 볼 수 있듯이 LINKS의 형식은 source_path,target_path이며, source_path는 wheel 내 임의의 네임스페이스 또는 패키지 루트의 루트에 상대적인 경로입니다. target_path는 wheel 내 패키지 또는 모든 패키지의 네임스페이스에 있는 non-dangling 경로, 즉 wheel의 콘텐츠를 추출한 후 파일 시스템에 존재하는 경로입니다. 따라서 wheel에 여러 패키지가 포함된 경우 wheel 내 패키지에 있는 모든 경로가 허용됩니다.
설치 프로그램 동작 사양
설치 프로그램은 LINKS 파일에 포함된 모든 링크의 경로를 먼저 확인한 후, source_path또는 target_path가 유효한지 반드시 결정해야 합니다. 설치 프로그램은 source_path와 target_path가 휠에서 제공되는 모든 네임스페이스 또는 패키지 내부에 위치하는지 반드시 확인해야 합니다. 설치 프로그램은 휠의 순환 심볼릭 링크를 반드시 거부해야 합니다. 심볼릭 링크의 긴 연결(심볼릭 링크를 여러 번 반복해서 가리키는 심볼릭 링크)이 설치 프로그램이 설정한 제한을 초과하는 경우, 설치 프로그램은 오류를 발생시킬 수 있습니다.
설치 프로그램은 심볼릭 링크가 포함된 휠을 처리할 때 다음 단계를 반드시 따라야 합니다.
.dist-info에LINKS파일이 존재하는지 확인하십시오. 존재하지 않으면 추가 단계는 필요하지 않습니다.- wheel 1.x에서와 같이 wheel 패키지와 데이터 디렉터리의 모든 파일을 추출하십시오.
- 각
source_path및target_path쌍에 대해, 방금 추출한 패키지 네임스페이스 중 하나에target_path가 존재하는지 확인하십시오. - 다음으로 사이트 디렉터리에서 각 쌍에 대해 설치 프로그램이 어떤 종류의 링크를 만들 수 있는지 확인하십시오. 설치 프로그램이 현재 플랫폼에서 파일/폴더
target_path에 대한 링크를 만들 수 없다면, 오류를 반드시 발생시켜야 합니다. 실패하는 경우의 예로는 파일 대상을 가리키는 POSIX 심볼릭 링크가 있으며, 이때 설치 프로그램은 Windows에서 실행되고 심볼릭 링크는 만들 수 없지만 접합점은 만들 수 있습니다. 이 경우 설치 프로그램은 링크를 처리할 수 없으므로 오류를 반드시 발생시켜야 합니다. - 마지막으로 설치 프로그램은
source_path와target_path사이에 플랫폼에 적합한 링크를 반드시 추가해야 합니다.
설치 도구는 심볼릭 링크를 처리할 때 기본적으로 심볼릭 링크를 생성하는 대신 파일을 복사해서는 안 됩니다. 설치 도구는 대체 구성이나 명령줄 플래그를 통해 이러한 동작을 사용할 수 있도록 할 수 있습니다.
빌드 백엔드 사양
휠을 생성할 때, 빌드 백엔드는 휠에 심볼릭 링크를 포함할지 결정할 때 심볼릭 링크를 대상과 동일하게 취급해야 합니다. 빌드 백엔드는 LINKS 파일에 끊어진 심볼릭 링크가 없는지 확인해야 합니다. 빌드 백엔드는 빌드에 포함될 플랫폼 관련 심볼릭 링크를 인식해야 합니다. POSIX 시스템에서는 일반적으로 심볼릭 링크이며, Windows에서는 심볼릭 링크와 정션을 포함합니다.
하위 호환성
심볼릭 링크를 도입하려면 휠 형식의 주 버전을 증가시켜야 합니다. 이는 새 휠 형식을 사용하는 새 휠이 이전 설치 도구에서 오류를 발생시킨다는 의미입니다. wheel specification에 따릅니다.
“Wheel 2.0”에 대해서는 PEP 777을 참조하십시오.
보안 관련 사항
심볼릭 링크는 주의 깊게 처리하지 않으면 매우 위험할 수 있습니다. 간단한 예로 사용자가 sudo pip install malicious를 실행하고 아무런 보호 조치가 없다면, 악성 패키지가 /etc/shadow를 덮어쓰고 시스템의 비밀번호 해시를 바꾸어 악의적인 로그인을 허용할 수 있습니다.
이 PEP에서는 위와 같은 공격이 발생하지 않도록 휠의 심볼릭 링크에 대해 설치 도구가 수행해야 하는 검사 요구 사항을 몇 가지 제시합니다. 따라서 설치 도구가 이러한 보안 보호 조치를 신중하게 구현하고 패키지 설치 시 악의적인 사용을 방지하는 것이 매우 중요합니다.
특히 설치 도구는 다음 검사를 반드시 수행해야 합니다:
- 심볼릭 링크가 휠에서 제공되는 어떠한 패키지나 네임스페이스의 외부도 가리키지 않는지
- 심볼릭 링크가 끊어지지 않았는지(설치 시점에 대상이 존재하는지)
- 서비스 거부 요청을 방지하기 위해 특정 검사 깊이에서 중단하면서 심볼릭 링크가 순환하지 않는지
제거할 때 심볼릭 링크를 따라가지 마십시오.
이 내용을 가르치는 방법
생태계 전체에 변경 사항이 전파되면 최종 사용자는 휠의 심볼릭 링크가 주는 이점을 투명하게 경험해야 합니다. 플랫폼에서 심볼릭 링크를 지원하지 않는 경우 설치 도구가 명확한 오류 메시지를 제공하고 설치가 실패한 이유를 설명하는 것이 중요합니다.
라이브러리를 빌드하는 사람들을 위해 packaging.python.org의 문서에서는 휠의 심볼릭 링크 사용 사례와 주의 사항(특히 플랫폼 지원)을 설명해야 합니다. 그 밖의 경우에는 일반 파일을 처리하는 것과 동일한 방식으로 빌드 백엔드가 이를 투명하게 처리해야 합니다.
참조 구현
TODO
거부된 아이디어
어디서나 POSIX 심볼릭 링크만 사용하기
이 PEP는 향후 도입될 수 있는 PEP 660 편집 가능 설치에 LINKS를 사용할 수 있도록 허용하고자 합니다. 이 미래의 PEP는 Windows를 지원해야 하므로 정션을 사용해야 할 수 있습니다.
LINKS에서 정션을 사용하지 마십시오.
정션은 Windows에서 폴더 간 심볼릭 링크를 지원하는 제한적인 방법입니다. 정션은 파일을 지원하지 않습니다. 이 PEP에서는 사용자가 폴더만 다른 위치에 연결하려 할 수 있고 향후 PEP 660 구현이 이 기능에 의존해야 할 수 있으므로 정션을 허용합니다.
RECORD 메타데이터 파일에 심볼릭 링크를 넣으십시오.
이렇게 할 수는 있지만 RECORD 파일이 복잡해집니다. 또한 가장 간단한 구현에서는 레코드 끝에 대상을 배치하게 됩니다. 그러면 줄을 훑어보면서 휠에 어떤 심볼릭 링크가 존재하는지 시각적으로 확인하기가 더 어려워집니다.
라이브러리 유지 관리자는 Python을 사용하여 라이브러리를 찾으십시오.
Python을 사용하여 라이브러리를 찾으면 훨씬 더 쉬워집니다. 그러나 libtorch와 같은 일부 라이브러리는 확장 모듈에서 사용되며 자체적으로 종속성을 로드해야 합니다. 일부 컴파일된 라이브러리는 Python을 사용하여 로더 종속성을 찾을 수 없습니다.
하드 링크 지원을 포함하십시오.
이 PEP에서는 하드 링크와 관련된 동작을 지정하지 않습니다. 이는 의도적인 결정입니다. 이 내용은 향후 PEP의 확장 사항으로 남겨 둡니다.
미해결 문제
PEP 660 및 편집 가능 설치 지원 연기
이 PEP에서는 PEP 660 편집 가능 설치 메커니즘의 사양과 구현을 이후 PEP에서 해결할 사항으로 남겨 두는데, 이를 이 PEP에서 지정해야 합니까?
보안
새로운 보안 취약점이 발생하지 않도록 허용하는지 확인하기 위해 이 PEP를 검토해야 합니다. 사용자를 보호하기 위해 심볼릭 링크의 소스 또는 대상에 적용해야 할 다른 제한 사항이 있습니까?
패키지 간 심볼릭 링크 허용
이는 휠 간에 대형 라이브러리와 같은 종속성을 분할하면서 주 상위 휠에서 사용할 수 있게 하려는 프로젝트에 유용할 수 있습니다.
LINKS의 형식
현재 형식은 RECORD에서 파생되지만, 더 나은 형식이 있을 수도 있습니다.
이전 논의
https://discuss.python.org/t/symbolic-links-in-wheels/1945/25
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.