Build.distのメモ

概要

RasberyPi用のGentooであるGenPi64というプロジェクトがある。

ただアップされているイメージが古い、様子。 新しいGentooを試したい。

GenPi64のイメージを作製するには GenPi64/Build.Dist: Build scripts for building GenPi64 images.を使う。

仕組みは非常に合理的というか良くできている、が、うまく動かなかったので仕組みを調べている。 これはそのメモ。

手順

事前準備

必要なパッケージ追加

sudo emerge --ask dev-python/lockfile dev-python/pychroot emerge dev-python/iniparse
sudo QEMU_USER_TARGETS="aarch64 arm" QEMU_SOFTMMU_TARGETS="aarch64 arm" USE="static-libs" emerge --changed-use --ask  --newuse  --quiet app-emulation/qemu

quick start

https://github.com/GenPi64/Build.Dist/ を git pull し、ディレクトリに移動

sudo -s
bash
export PROJECT="GenPi64Systemd"
. env.sh
sh build.sh

仕組み

sh build.sh を行った際の進み方

[build.sh)[https://github.com/GenPi64/Build.Dist/blob/559dd933b88a79d9bd5e1efa360b45c7a42ad31d/build.sh#L1]

ここから始まる。 環境変数の設定を行ったり、ターゲット(OpenRC, systemdなど)に応じてディレクトリを作製し、プロジェクトごとに用意してあるjsonから動作する。

jsonはincludeと書かれた箇所があり、その場合、該当するjsonを読み込み、対象の作業が膨らんでいく。 このincludeの仕組みは美しいと思う。 GentooであればOpenRCであれ、systemdであれ共通化できる作業はある、それらのタスクは共通化できるように作られている。 また個々のタスクが完了したかチェックする仕組みもあり、成功したタスクについては行わず続きから再開する。

build.shのこの箇所からincludejsonが始まる

includejson

excecute(manifest)で実行しているようだ。

この辺で環境変数を読み込んでいる ただ実際のemergeの際にはchroot環境で実行されるので環境変数は引き継ぐ意図ではない。

emerge

ヒアドキュメントで都度、スクリプトを生成し、実行している

この${EXTRA_EMERGE_ENV}って何が入っているんだろう

cat <<- EOF > "${PROJECT_DIR}/chroot/em-$$"
	#!/usr/bin/env bash
	set -evx
	source /etc/profile
	export SHELL="/bin/bash"
	export TERM="linux"
	export MAKEOPTS="-j$(nproc) -l$(nproc)"
	${USE}
	${EXTRA_EMERGE_ENV}
	emerge $1
EOF    

chmod +x "${PROJECT_DIR}/chroot/em-$$"

"${SCRIPTS}/chroot.py" "/em-$$"

この都度、作られるスクリプトは chroot.pyから起動している。

chroot.py

$CHROOT_CMDのあるなしで分岐、 なければ更に pyrootとsystemdpnspawnで分岐している

$CHROOT_CMDが無ければ /sbin/openrc-run があるか /proc/1/exe がsystemdにリンクしているかで分岐

私の環境がどのchrootで実行されるのか確認する。

$CHROOT_CMDは無かった。

declare -x CHOST_arm64="aarch64-unknown-linux-gnu"
declare -x CHOST_default="aarch64-unknown-linux-gnu"
declare -x CHROOT_DIR="/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/build/GenPi64Systemd/chroot"
declare -- CMAKE_BINARY="cmake"

とすると、/sbin/openrc-run かあるか、/proc/1/exe があるかか? /sbin/openrc-runがあった。とすると下記の処理に入ると思われる。

# Add new behavior
elif os.path.exists('/sbin/openrc-run'):
    os.execvpe('pychroot',
               ['pychroot',
                '-B', f'{os.environ["CCACHE_DIR"]}:/var/tmp/ccache',
                '-B', f'{os.environ["BINPKGS_DIR"]}:/var/cache/binpkgs',
                '-B', f'{os.environ["DISTFILES_DIR"]}:/var/cache/distfiles',
                os.environ['CHROOT_DIR'],
                *sys.argv[1:]], os.environ)

とするとpychrootの振る舞いが気になる。

chroot.pyでprint文を追加して環境変数を出力した。

environ({
'BINPKGS_DIR': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/build/GenPi64Systemd/packages', 
'CHROOT_DIR': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/build/GenPi64Systemd/chroot', 
'OVERLAYS_CACHE_DIR': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/build/GenPi64Systemd/overlays-cache', 
'PROJECT_DIR': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/build/GenPi64Systemd', 
'PWD': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist', 
'CCACHE_DIR': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/build/GenPi64Systemd/ccache', 
'PARSERS': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/parsers', 
'CONFIG_DIR': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/config', 
'CALLBACKS': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/callbacks', 
'BINARY_ASSETS': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/build/GenPi64Systemd/build-binary-assets', 
'SCRIPTS': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/scripts', 
'TERM': 'screen-256color', 
'SHLVL': '1', 
'DISTFILES_DIR': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/build/GenPi64Systemd/distfiles', 
'BASEDIR': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist', 
'PROJECT': 'GenPi64Systemd', 
'_': '/net/10.10.254.10/homes/kaoru/workspace/git/github.com/tin-machine/Build.Dist/scripts/chroot.py', 
'LC_CTYPE': 'C.UTF-8'
})

https://github.com/pkgcore/pychroot

A simple chroot equivalent is also installed as pychroot. It can be used in a similar fashion to chroot; however, it also performs the bind mounts previously mentioned so the environment is usable. In addition, pychroot supports specifying custom bind mounts,

environmentはそのまま使えそうでもあるが. いや、そのままでとは言えないか。 少し検証用のスクリプトが欲しいところ。

distccの設定について

(chrootしてビルドが進行するが、進行中、distccを利用しているかは別途確認する必要がある)

レポジトリの parsers/distcc/distcc でdistccの設定が書き込まれる。

#!/bin/bash -ex
echo > ${CHROOT_DIR}/etc/distcc/hosts
for((i=0;i<$(${PARSERS}/config/getconfig distcc "#");i++)); do
    echo $(${PARSERS}/config/getconfig distcc $i) >> ${CHROOT_DIR}/etc/distcc/hosts
done

${PARSERS}/config/getconfig は下記の内容、ビルドしているマシンのdistccを見てくれるようだ。

#!/usr/bin/env python3
import sys
import os
sys.path.insert(0, os.environ['CONFIG_DIR'])

from pyconfig import config

t = config

for i in sys.argv[1:]:
    if i[0] == '*':
        print(str.join(i[1:], t))
        break
    if i.endswith('?'):
        print(t.get(i[:-1], ""))
        break
    if i.isdigit():
        i = int(i)
        if isinstance(t, dict):
            t = list(t)[i]
            print(t)
            break
    if i == '#':
        print(len(t))
        break

    t = t[i]
else:
    print(t)

./parsers/includejson/includejson が様々なジョブを実行している模様

parsers/includejson/includejson が様々な処理している

様々なジョブがあるが、parsers/配下に様々な処理を行うスクリプトがある。 (いろいろな処理を自動化していて凄い…)

{'name': 'locale', 'deps': ['etc'], 'parser': 'rawcommand', 'args': ['eselect locale set en_US.utf8']},

上記の処理を行うパーサーは parsers/rawcommand/rawcommand になる。

./build/GenPi64OpenRC/chroot/em-config.json に様々な設定がある

手動でchrootする方法

mountする必要があるのでrootで行う。

cd build/GenPi64Systemd/chroot
mount -o bind /dev dev
mount -t devpts devpts dev/pts/
mount -t proc none proc/
mount -t sysfs none  sys
chroot ./ /bin/bash

私の検証中のページ

build-dist-trouble

参考

binfmtの説明

JF: Linux Kernel 3.x/2.6 Documentation: binfmt_misc.txt

systemdだとhostnameが設定できない可能性がある

Systemd image can’t set hostname from DHCP when polkit is not installed · Issue #129 · GenPi64/Build.Dist

distccを検証している情報がある

Build Fails 1/4/2023 · Issue #179 · GenPi64/Build.Dist

crudini でエラーが出る?

Broken-wont-work: Use crudini to set initramfs by jonesmz · Pull Request #142 · GenPi64/Build.Dist

シェル関連で修正が入ったタイミング

Some minor improvements for the shell code by maffblaster · Pull Request #157 · GenPi64/Build.Dist

binfmt.shだが、私がコメントできるかも?

scripts/binfmt.sh and parsers/qemu should check the target architecture · Issue #120 · GenPi64/Build.Dist