다음을 통해 공유


NuGet 플랫폼 간 플러그 인

NuGet 4.8 이상에서는 플랫폼 간 플러그 인에 대한 지원이 추가되었습니다. 이는 엄격한 작업 규칙을 준수해야 하는 새로운 플러그 인 확장성 모델을 빌드하여 달성되었습니다. 플러그 인은 NuGet 클라이언트가 별도의 프로세스에서 시작하는 자체 포함 실행 파일(.NET Core 세계의 실행 파일)입니다. 이것은 한 번 작성하고, 모든 곳에서 실행 가능한 플러그인입니다. 모든 NuGet 클라이언트 도구에서 작동합니다. 플러그 인은 모든 프로그래밍 언어로 작성할 수 있지만 가장 쉬운 플러그 인 개발 및 설치 환경은 .NET입니다. NuGet 클라이언트와 플러그 인 간의 버전이 지정된 통신 프로토콜이 정의됩니다. 시작 핸드셰이크 중에 2개 프로세스는 프로토콜 버전을 협상합니다.

작동 방식

개략적인 워크플로는 다음과 같이 설명할 수 있습니다.

  1. NuGet은 사용 가능한 플러그 인을 검색합니다.
  2. 해당하는 경우 NuGet은 플러그 인을 우선 순위 순서로 반복하고 하나씩 시작합니다.
  3. NuGet은 요청을 서비스할 수 있는 첫 번째 플러그 인을 사용합니다.
  4. 플러그 인은 더 이상 필요하지 않을 때 종료됩니다.

일반 플러그 인 요구 사항

현재 프로토콜 버전은 2.0.0입니다. 이 버전에서 요구 사항은 다음과 같습니다.

  • NuGet 클라이언트 도구의 현재 보안 컨텍스트에서 상태 비스테이스 실행을 지원합니다. 예를 들어 NuGet 클라이언트 도구는 나중에 설명한 플러그 인 프로토콜 외부에서 권한 상승 또는 추가 초기화를 수행하지 않습니다.
  • 명시적으로 지정하지 않는 한 비대화형이어야 합니다.
  • 협상된 플러그 인 프로토콜 버전을 준수합니다.
  • 적절한 기간 내에 모든 요청에 응답합니다.
  • 진행 중인 작업에 대한 취소 요청을 수용합니다.

PATH 환경 변수(예: dotnet tool을 통해 설치된)에서 검색된 플러그인은 파일 이름 패턴 nuget-plugin-*과 추가적으로 일치해야 합니다. nuget-plugin- 부분은 모두 소문자로 작성해야 합니다.

NuGet 6.12(MSBuild 17.12 및 .NET SDK 9.0.100) 및 이전 버전에서도 Windows에서 Authenticode에 서명해야 했습니다.

기술 사양은 다음 사양에 자세히 설명되어 있습니다.

클라이언트 - 플러그 인 상호 작용

NuGet 클라이언트 도구 및 플러그 인은 표준 스트림(stdin, stdout, stderr)을 통해 JSON과 통신합니다. 모든 데이터는 UTF-8로 인코딩되어야 합니다. 플러그 인은 인수 "-Plugin"을 사용하여 시작됩니다. 사용자가 이 인수 없이 플러그 인 실행 파일을 직접 실행하는 경우 플러그 인은 프로토콜 핸드셰이크를 기다리는 대신 정보 메시지를 제공할 수 있습니다. 프로토콜 핸드셰이크 시간 제한은 5초입니다. 플러그 인은 가능한 한 적은 양으로 설치를 완료해야 합니다. NuGet 클라이언트 도구는 NuGet 원본에 대한 서비스 인덱스를 전달하여 플러그 인의 지원되는 작업을 쿼리합니다. 플러그 인은 서비스 인덱스로 지원되는 서비스 유형의 존재를 확인할 수 있습니다.

NuGet 클라이언트 도구와 플러그 인 간의 통신은 양방향입니다. 각 요청에는 5초의 시간 제한이 있습니다. 작업이 더 오래 걸리는 경우 각 프로세스는 요청 시간이 초과되지 않도록 진행률 메시지를 보내야 합니다. 1분 동안 비활성 상태이면 플러그 인이 유휴 상태로 간주되어 종료됩니다.

플러그 인 설치 및 검색

NuGet은 규칙 기반 디렉터리 구조에서 플러그 인을 검색하고 PATH 환경 변수를 검색합니다.

관습 기반 탐색

CI/CD 시나리오 및 전원 사용자는 환경 변수를 사용하여 동작을 재정의할 수 있습니다. 환경 변수를 사용하는 경우 절대 경로만 허용됩니다. ** NuGet 도구의 5.3 버전 이상부터 NUGET_NETFX_PLUGIN_PATHSNUGET_NETCORE_PLUGIN_PATHS을 사용할 수 있습니다.

  • NUGET_NETFX_PLUGIN_PATHS - .NET Framework 기반 도구(NuGet.exe/MSBuild.exe/Visual Studio)에서 사용할 플러그 인을 정의합니다. NUGET_PLUGIN_PATHS보다 우선합니다. (NuGet 버전 5.3 이상만 해당)
  • NUGET_NETCORE_PLUGIN_PATHS - .NET Core 기반 도구(dotnet.exe)에서 사용할 플러그 인을 정의합니다. NUGET_PLUGIN_PATHS보다 우선합니다. (NuGet 버전 5.3 이상만 해당)
  • NUGET_PLUGIN_PATHS - 우선 순위가 유지되는 NuGet 프로세스에 사용할 플러그 인을 정의합니다. 이 환경 변수가 설정되면 규칙 기반 검색을 재정의합니다. 프레임워크 특정 변수 중 하나가 지정된 경우 무시됩니다.
  • NuGet 홈 위치에 있는 사용자 위치 %UserProfile%/.nuget/plugins. 이 위치는 재정의할 수 없습니다. .NET Core 및 .NET Framework 플러그 인에 다른 루트 디렉터리가 사용됩니다.
프레임워크 루트 검색 위치 에 의해 사용됨
.NET 코어 %UserProfile%/.nuget/plugins/netcore dotnet CLI
.NET Framework %UserProfile%/.nuget/plugins/netfx MSBuild, NuGet.exe, Visual Studio

각 플러그 인은 자체 폴더에 설치해야 합니다. 플러그 인 진입점은 .NET Core용 .dll 확장과 .NET Framework용 .exe 확장이 있는 설치된 폴더의 이름이 됩니다.

.nuget
    plugins
        netfx
            myPlugin
                myPlugin.exe
                nuget.protocol.dll
                ...
        netcore
            myPlugin
                myPlugin.dll
                nuget.protocol.dll
                ...

PATH 검색

NuGet 6.13부터 NuGet은 PATH 환경 변수에 제공된 각 디렉터리에서 패턴nuget-plugin-*과 일치하는 파일을 검색합니다. 패턴 일치는 대/소문자를 구분하며 nuget-plugin- 완전히 소문자로 작성해야 합니다. Windows에서는 파일의 확장명이 .exe 또는 .bat 여야 합니다. Linux 및 Mac에서 파일에 실행 비트 집합이 있어야 합니다.

이렇게 하면 명령, WinGet, Linux 배포의 패키지 관리자 또는 실행 파일을 사용자의 PATH에 배치할 수 있는 다른 메서드를 통해 dotnet tool NuGet 플러그 인을 설치할 수 있습니다. 이렇게 하면 NuGet 플러그 인을 모든 프로그래밍 언어로 작성할 수 있습니다(이전에는 Linux 및 Mac용 플러그 인을 .NET으로 작성해야 합니다).

플러그 인은 .NET에서 개발되어 NuGet.Protocol 패키지를 사용하여 json RPC 코드를 작성할 필요가 없으며 고객이 플러그 인을 통해 dotnet package search nuget-plugin검색할 수 있도록 하는 것이 좋습니다.

지원되는 작업

새 플러그 인 프로토콜에서 두 가지 작업이 지원됩니다.

작업 이름 최소 프로토콜 버전 최소 NuGet 클라이언트 버전
패키지 다운로드 1.0.0 4.3.0
인증 2.0.0 4.8.0

올바른 런타임에서 플러그 인 실행

dotnet.exe 시나리오의 NuGet의 경우 플러그 인은 dotnet.exe특정 런타임에서 실행할 수 있어야 합니다. 플러그인 공급자와 소비자는 호환되는 dotnet.exe/플러그인 조합이 사용되도록 해야 합니다. 예를 들어 2.0 런타임의 dotnet.exe 2.1 런타임에 대해 작성된 플러그 인을 사용하려고 할 때 사용자 위치 플러그 인에 잠재적인 문제가 발생할 수 있습니다.

기능 역량 캐싱

플러그 인의 보안 확인 및 인스턴스화는 비용이 많이 듭니다. 다운로드 작업은 인증 작업보다 훨씬 빈번하게 수행되지만, 평균 NuGet 사용자에게는 인증 플러그 인만 있을 가능성이 높습니다. 환경을 개선하기 위해 NuGet은 지정된 요청에 대한 작업 클레임을 캐시합니다. 이 캐시는 플러그 인 키가 플러그 인 경로인 플러그 인당이며 이 기능 캐시의 만료는 30일입니다.

캐시는 %LocalAppData%/NuGet/plugins-cache에 위치하며 환경 변수 NUGET_PLUGINS_CACHE_PATH로 재정의될 수 있습니다. 이 캐시를 지우려면 옵션을 사용하여 locals 명령을 plugins-cache 실행할 수 있습니다. all 이제 로컬 옵션도 플러그 인 캐시를 삭제합니다.

프로토콜 메시지 인덱스

프로토콜 버전 1.0.0 메시지:

  1. 닫기

    • 요청 방향: NuGet -> 플러그 인
    • 요청에 페이로드가 포함되지 않습니다.
    • 응답이 필요하지 않습니다. 적절한 응답은 플러그 인 프로세스가 즉시 종료되는 것입니다.
  2. 패키지의 파일 복사

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 패키지 ID 및 버전
      • 패키지 원본 리포지토리 위치
      • 대상 디렉터리 경로
      • 대상 디렉터리 경로에 복사할 패키지의 파일 목록
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 작업이 성공한 경우 대상 디렉터리에 복사된 파일에 대한 전체 경로 열거 가능
  3. 패키지 파일 복사(.nupkg)

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 패키지 ID 및 버전
      • 패키지 원본 리포지토리 위치
      • 대상 파일 경로
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
  4. 자격 증명 가져오기

    • 요청 방향: 플러그 인 -> NuGet
    • 요청에는 다음이 포함됩니다.
      • 패키지 원본 리포지토리 위치
      • 현재 자격 증명을 사용하여 패키지 원본 리포지토리에서 가져온 HTTP 상태 코드
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 사용자 이름(사용 가능한 경우)
      • 암호(사용 가능한 경우)
  5. 패키지에서 파일 가져오기

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 패키지 ID 및 버전
      • 패키지 원본 리포지토리 위치
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 작업이 성공한 경우 패키지의 파일 경로 열거 가능
  6. 작업 클레임 가져오기

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 패키지 원본에 대한 서비스 index.json
      • 패키지 원본 리포지토리 위치
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 작업이 성공한 경우 지원되는 작업의 열거 가능(예: 패키지 다운로드)입니다. 플러그 인이 패키지 원본을 지원하지 않는 경우 플러그 인은 지원되는 빈 작업 집합을 반환해야 합니다.

비고

이 메시지는 버전 2.0.0에서 업데이트되었습니다. 클라이언트가 이전 버전과의 호환성을 유지할 책임이 있습니다.

  1. 패키지 해시 가져오기

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 패키지 ID 및 버전
      • 패키지 원본 리포지토리 위치
      • 해시 알고리즘
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 작업이 성공한 경우 요청된 해시 알고리즘을 사용하는 패키지 파일 해시
  2. 패키지 버전 가져오기

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 패키지 ID
      • 패키지 원본 리포지토리 위치
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 작업이 성공한 경우 패키지 버전 열거 가능
  3. 서비스 인덱스 가져오기

    • 요청 방향: 플러그 인 -> NuGet
    • 요청에는 다음이 포함됩니다.
      • 패키지 원본 리포지토리 위치
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 작업이 성공한 경우 서비스 인덱스
  4. 핸드셰이크

    • 요청 방향: NuGet <-> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 현재 플러그 인 프로토콜 버전
      • 지원되는 최소 플러그 인 프로토콜 버전
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 작업이 성공한 경우 협상된 프로토콜 버전입니다. 오류가 발생하여 플러그 인이 종료됩니다.
  5. 초기화

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • NuGet 클라이언트 도구 버전
      • NuGet 클라이언트 도구 유효 언어입니다. 사용하는 경우 ForceEnglishOutput 설정을 고려합니다.
      • 프로토콜 기본값을 대체하는 기본 요청 시간 제한입니다.
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드입니다. 오류가 발생하여 플러그 인이 종료됩니다.
  6. 로그

    • 요청 방향: 플러그 인 -> NuGet
    • 요청에는 다음이 포함됩니다.
      • 요청에 대한 로그 수준
      • 기록할 메시지
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드입니다.
  7. NuGet 프로세스 종료 모니터링

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • NuGet 프로세스 ID
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드입니다.
  8. 패키지 프리페치

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 패키지 ID 및 버전
      • 패키지 원본 리포지토리 위치
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
  9. 자격 증명 설정

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 패키지 원본 리포지토리 위치
      • 마지막으로 알려진 패키지 원본 사용자 이름(사용 가능한 경우)
      • 마지막으로 알려진 패키지 원본 암호(사용 가능한 경우)
      • 마지막으로 알려진 프록시 사용자 이름(사용 가능한 경우)
      • 마지막으로 알려진 프록시 암호(사용 가능한 경우)
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
  10. 로그 수준 설정

    • 요청 방향: NuGet -> 플러그 인
    • 요청에는 다음이 포함됩니다.
      • 기본 로그 수준
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드

프로토콜 버전 2.0.0 메시지

  1. 작업 클레임 가져오기
  • 요청 방향: NuGet -> 플러그 인

    • 요청에는 다음이 포함됩니다.
      • 패키지 원본에 대한 서비스 index.json
      • 패키지 원본 리포지토리 위치
    • 응답에는 다음이 포함됩니다.
      • 작업의 결과를 나타내는 응답 코드
      • 작업이 성공한 경우 지원되는 작업의 열거형입니다. 플러그 인이 패키지 원본을 지원하지 않는 경우 플러그 인은 지원되는 빈 작업 집합을 반환해야 합니다.

    서비스 인덱스 및 패키지 원본이 null이면 플러그 인이 인증으로 응답할 수 있습니다.

  1. 인증 자격 증명 가져오기
  • 요청 방향: NuGet -> 플러그 인
  • 요청에는 다음이 포함됩니다.
    • Uri
    • 재시도여부
    • 비상호적
    • CanShowDialog
  • 응답에는 다음이 포함될 것입니다.
    • 사용자 이름
    • 암호
    • 메시지
    • 인증 유형 목록
    • 메시지응답코드