메타데이터

메타데이터

freebsd에서 바이너리 패키지를 만들려고 합니다. 내가 찾은 모든 가이드는 기본적으로 포트를 사용하여 설치된 소프트웨어에서 바이너리 패키지를 빌드한다고 말합니다. 포트를 설치하지 않고 이 작업을 수행할 수 있는 방법을 찾고 있습니다.

가능합니까?

내 코드는 golang에 있습니다. 따라서 소스 코드에는 Go 코드와 구성 파일에서 컴파일된 바이너리가 포함되어 있습니다.

답변1

Packageformat에 대한 문서는 여기에서 찾을 수 있습니다. https://wiki.freebsd.org/pkgng#Package_format

패키지를 만들기 위해 소프트웨어를 설치할 필요는 없습니다. 포트에서 패키징하는 동안 임시 디렉터리에 설치된 다음 패키징됩니다.

답변2

패키지 형식 문서(pkgng가 pkg가 되었기 때문에)가 이제 있습니다.https://github.com/freebsd/pkg#pkgfmt.

파일은 .pkg기본적으로 tar 아카이브이며 선택적으로 몇 가지 표준 도구 중 하나와 몇 가지 추가 제약 조건을 사용하여 압축됩니다.

첫째, 아카이브의 첫 번째 파일은 메타데이터입니다. 두 개의 파일이 지정되고 이름 +MANIFEST+COMPACT_MANIFEST경로도 없고 선행도 없습니다 /. 다음은 설치할 파일이며 각 파일에는 전체 대상 경로( 로 시작 /)가 있습니다.

메타데이터

+MANIFEST사양에 따르면 YAML과 JSON이 다소 혼합된 UCL 형식의 파일입니다. 순수 JSON이 작동합니다(패키지를 설치하는 데 사용되는 경우 pkg add blah.pkg). 이는 FreeBSD 저장소에서 패키지를 확인할 때 발견했습니다.

매니페스트 값은 에 설명된 대로 makefile 변수에 크게 해당합니다.https://docs.freebsd.org/en/books/porters-handbook. 구체적으로:

name패키지에 대해 선택한 이름입니다.

version버전이며, 주어진 두 버전 중 어느 버전이 더 최신인지 결정하기 위한 몇 가지 규칙을 따릅니다.

origin저장소에 있는 패키지의 물리적 위치가 형식인 경우 category/namename값은 동일합니다 name. 추가 범주는 에서 지정할 수 있습니다 categories.

comment패키지에 대한 한 줄 설명입니다.

arch비슷한 형태를 취합니다 freebsd:13:x86:64. freebsd:*특정 아키텍처 및/또는 운영 체제 버전에 의존하지 않는 패키지(예: 나를 위해 설치됨)에 대한 와일드카드 값입니다.

wwwmaintainer각각 프로젝트의 웹사이트 URL과 관리자 이메일 주소입니다.

prefix일반적으로 그렇습니다 . 그러나 패키지가 및 /usr/local에 설치되어 있어도 설치에는 영향을 미치지 않는 것 같습니다 ./opt/etc

licenselogic: single라이센스가 1개만 있는 경우, or여러 라이센스 중에서 선택할 수 있는 경우입니다.

licenses, 등 의 핸들로 참조되는 라이센스 목록입니다 GPLv3+. 자세한 내용은 포터 매뉴얼을 참조하세요.GPLv2BSD

flatsize설치된 모든 파일의 전체 크기인 것 같습니다. 내가 확인한 패키지의 값이 약간 다르기 때문에 100% 확신할 수는 없지만, 이 가정을 사용하여 만든 패키지는 잘 설치되었습니다 pkg add.

users, groups패키지가 설치될 때 생성된 사용자 및 그룹인 것으로 보입니다(이것을 시도하지 않았으므로 이러한 항목이 실제로 거기에 언급된 사용자 및 그룹 생성을 트리거하는지 알 수 없습니다).

options: 확실하지 않습니다. 내 패키지가 제대로 설치되었습니다. 아니요.

desc패키지에 대한 더 긴(한 줄 이상) 설명입니다.

categories이 패키지가 나열해야 하는 다른 범주의 목록입니다. 여기 에서 카테고리가 origin반복되는 것으로 보입니다.

deps종속성, 이 패키지가 작동하는 데 필요한 다른 패키지입니다. 일반적으로 다음과 같은 형식을 취합니다.

  • name: {origin: category/name, version: 1.2.3}(최소 버전 필요) 또는 그냥
  • `name:{source:category/name} (모든 버전에 해당)

directories패키지에 의해 생성된 디렉터리인 것 같습니다. 항목 형식은 /usr/local/share/foo-1.0: y; 이 값이 무엇인지 잘 모르겠습니다. 제거할 때 디렉터리를 삭제하시겠습니까? 그러나 이 항목이 없으면 패키지가 정상적으로 설치됩니다(필요한 경우 디렉터리가 생성됨).

files: 파일 및 해당 SHA256 체크섬입니다. 아카이브의 파일에 여기에 항목이 없으면 어떻게 되는지 잘 모르겠습니다. 전혀 설치되지 않았습니까, 아니면 설치되었지만 SHA256 확인 없이 설치되었습니까?

scripts설치 또는 제거 전, 도중, 후에 실행되는 스크립트입니다.

+COMPACT_MANIFEST일부 값을 생략하면 됩니다 +MANIFEST. 전자는 저장소의 패키지를 나열하는 데 사용되고 후자는 실제 설치를 수행하는 데 사용됩니다. +MANIFEST패키지를 설치하지 않고 사용하는 것만으로도 +COMPACT_MANIFEST작동하는 것처럼 보이지만 패키지를 공식 저장소에 넣으려고 하면 부작용이 발생할 수 있습니다.

패키지를 구축하다

나는 간단한 쉘 스크립트만으로 FreeBSD에 설치할 수 있는 패키지를 엮어냈습니다. 이것은 좋은 부작용이 있습니다. 심지어 BSD를 빌드할 필요도 없습니다. 이는 네이티브 코드가 없는 경우 유용합니다.

가장 간단한 방법은 YAML에서 스켈레톤 매니페스트를 구축하고 모든 것을 동적으로 생성하고 JSON으로 변환하는 것입니다 files.flatsize

쉘 스크립트 예:

FLATSIZE=0

create_files_entry() {
    # TODO if the file is a link, just insert '-'
    sha256sum $1 | sed -E 's,([a-fA-F0-9]*) *(.*),  \2: \1,' | sed $2
}

add_file() {
    [ -d $1 ] && return
    create_files_entry $1 $2 >> $(dirname $0)/cache/files.yaml
    tar -Pr -f $(dirname $0)/cache/data.tar --transform=$2 $1
    case `uname` in
        Linux)
            FLATSIZE=$(( FLATSIZE + $(stat -c %s $1) ))
            ;;
        FreeBSD)
            FLATSIZE=$(( FLATSIZE + $(stat -f %d $1) ))
            ;;
        *)
            echo "ERROR: unsupported build platform: `uname`"
            exit 1
            ;;
    esac
}

echo "files:" > cache/files.yaml

# the second parameter is a transformation to change the file path
add_file path/to/file 's,\./path/to/,/usr/local/foo/,'
# add more files in this manner as needed

echo "flatsize: $FLATSIZE" >> files.yaml
cat $manifest.yaml $cache/files.yaml | python3 -c 'import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin.read())))' > cache/+MANIFEST
# create new archive with +MANIFEST (without leading /)
tar -c -f cache/full.tar --transform='s,\./cache/,,' cache/+MANIFEST
tar -A cache/data.tar -f cache/full.tar
# compress and move to destination
xz cache/full.tar
mv cache/full.tar.xz out/$PKGNAME-$PKGVER.pkg

설치하다

생성된 pkg 파일은 이제 다음 명령을 사용하여 설치할 수 있습니다.

pkg add /path/to/foo-1.2.3.pkg

관련 정보