(TL; DR:初期状態と必須パッケージのリストが与えられたら、インストールする最小パッケージセットをどのように決定しますか?)
展開イメージにアクセスできないシステム用のUbuntuインストーラISOを作成しています。これは組み込みデバイスであり、基本パッケージといくつかのローカルに構築されたパッケージのみが必要です。さらに、すべての依存関係。たとえば、Qt/Xcb を使用しているため、libqt5*
さまざまなパッケージを導入する必要があります。
現在、私はインストーラのpool / extrasディレクトリに何を入れるかを決定するために無差別代入方法を使用しています。まず、debconfに対する回答に記載されているパッケージをSeedとして使用し、d-i pkgsel/include
次のコマンドを使用して再帰依存関係を見つけましたbash
。
# 1. Extract the dependencies from packages/*, removing version
# conditions and changing separator to newline.
# 2. Find the recursive dependencies of all these packages using
# package database, extracting Depends and PreDepends.
# 3. For each package we require:
# a. if we find it in our cache, just copy it into the ISO (using
# hard link for speed and space)
# b. else, if we find it already in the ISO, do nothing
# c. else, pass it through to step 4.
# 4. Search for matching packages in repositories that are not virtual
# or foreign-architecture.
# 5. Download matching package files to the ISO.
(for i in "$TOP/packages"/*.deb; do dpkg-deb -f $i depends; done) | sed 's/([^()]*)//g;s/[|,]/\n/g' \
| xargs -r apt-cache --recurse --important depends | sed -re 's/^ (Pre)?Depends://;/[<|:]/d;s/^ *//;' | sort -u \
| ( while read p; \
do test $(find "$TOP/extras" -name "${p}_*.deb" -exec mv '{}' "$REMASTER_HOME"/remaster-iso/pool/extras \; -printf "true" -quit) \
|| test $(find "$REMASTER_HOME"/remaster-iso/pool/{main,extras} -name "${p}_*.deb" -printf "true" -quit) \
|| echo $p; \
done; ) \
| uniq | sed -r 's/[^ ]+/!~rforeign!~v^&$/' | xargs -r aptitude -q2 -F '%p' search \
| (cd "$REMASTER_HOME"/remaster-iso/pool/extras; xargs -r apt-get download)
ここでは$TOP/packages
、シードパッケージディレクトリ、$TOP/extras
以前にダウンロードしたパッケージのキャッシュ、および解凍した$REMASTER_HOME"/remaster-iso
インストーラISOのルートディレクトリです。
apt-cache depends
上記のアプローチは機能しますが、各パッケージに対するすべての代替依存関係が報告されているため、実際に必要なものよりも多くを取得する傾向があります。たとえば、提供によってgrub-pc
異なり、およびおよびその依存関係が含まれます。また、によって異なりますので、私のスクリプトはすべてのビデオドライバを抽出します。しかし、私は依存関係を宣言したので、独自の要件を満たすことを望みます。debconf
cdebconf
debconf
debconf
cdebconf
xserver-xorg
xserver-xorg-video-all | xorg-driver-video
xserver-xorg-video-fbdev
私が望むのは、aptitude --download-only install ${MY_PACKAGES}
ターゲットシステムで実行されているものと同じです。しかし、もちろん、ビルドホストで実行すると、ほとんどのパッケージがすでにインストールされているため失われます。
現在視聴中python-apt
ライブラリを実行しているが実行中のホストではないターゲットシステムを初期化する例が見つかりませんでした。私が複製できる同様のことをした人はいますか?
それとも他の可能な方法がありますか?私はプリミティブで最小限のchrootを生成し、aptitude
その中でコマンドを実行することを検討していますが、これがメンテナンスの負担となり、他の人が自分のコンピュータに設定するのが難しいことが心配です。
パッケージを更新するときに必要な依存関係を見つけるために、このソリューション(新しい初期状態を含む)を使用できることを願っています。これは、ターゲットシステムのリムーバブルメディア用の一貫したセットを作成する必要があるためです(まだ展開イメージにアクセスできません)。 。
答え1
debootstrap
ディレクトリにクリーンな新しいシステムを設定し、 を使用してそのディレクトリで目的の操作を実行しchroot
、そこにあるすべてをインポートしますchrootdir/var/cache/apt/archives/
。
debootstrap
2回目の回答後の編集:今すぐマニュアルを確認した結果、必要な作業のほとんど(すべてではありません)を実行するために使用できるようです。以下で実行でき、オプションがfakeroot
あり、他のパッケージも追加できます。依存関係を混合して解決します。--download-only
--print-debs
--include
ソースを読む前に、2つの異なるソースセットを使用することは不明です。それもサポートしているようです:)
たとえば、
% fakeroot /usr/sbin/debootstrap --variant=minbase --download-only --include=dnsutils wheezy /tmp/foo "http://ftp.us.debian.org/debian file:///local_packages_dir/"
[...]
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Found additional required dependencies: [...]
I: Found additional base dependencies: [...]
[...]
少しオーバーヘッドがあります。
% du -sh /tmp/foo/var/cache/apt/archives/
40M /tmp/foo/var/cache/apt/archives/
% du -sh /tmp/foo/
68M /tmp/foo/
実際のダウンロードはapt-mirrorなどのツールを使用して最適化できるため、毎回リモートの場所から同じファイルはダウンロードされません。
答え2
これはbash
代わりにスクリプトですが、python-apt
私が見つけたのはdpkg-offline
同様のロジックが関連しています。私はそれがどのように機能するかを調べ、必要なダウンロードを実行するための独自のスクリプトを正常に作成しました。ルートではなく一般ユーザーとして再現可能です。
#!/bin/bash
set -e
die() {
exec >&2
printf '%s\n' "$@"
exit 1
}
test "$UID" != "0" || die \
"Do not run '$0' as root, because it will break your packages."
test -n "$1" || die \
"Usage: $0 <package-dir> [package] ..." \
" package may be followed by _ - + &m etc; like 'aptitude install'" \
" local packages must be listed in package-dir/Packages.gz" \
" downloaded packages are saved to package-dir/ubuntu"
PACKAGE_DIR="$1"; shift
BASE_DIR=$(mktemp -d)
trap 'rm -r "$BASE_DIR"' EXIT
(
cd $BASE_DIR
# Skeleton directory structure
mkdir -p \
etc/apt/preferences.d \
etc/apt/sources.list.d \
var/cache/apt/archives \
var/lib/apt/lists \
var/lib/aptitude \
var/lib/dpkg \
var/log
# Use GPG keys from host, and create empty dpkg status
cp /etc/apt/trusted.gpg etc/apt
touch var/lib/dpkg/status
cat >etc/apt/sources.list <<-EOF
# Locally-built packages
deb file://$PACKAGE_DIR /
# Upstream distribution to pillage
deb http://gb.archive.ubuntu.com/ubuntu/ trusty main restricted universe
EOF
# Don't let user's ~/.aptitude/* influence anything
export HOME="$BASE_DIR"
APT_OPTIONS=(-q2 \
-o "Apt::Architecture=amd64" \
-o "Apt::Install-Recommends=0" \
-o "Dir::Etc=$BASE_DIR/etc/apt" \
-o "Dir::State=$BASE_DIR/var/cache/apt" \
-o "Dir::Cache=$BASE_DIR/var/cache/apt" \
-o "Dir::Cache::Archives=$BASE_DIR/var/cache/apt/archives" \
-o "Dir::Log=$BASE_DIR/var/log" \
-o "Dir::State::Lists=$BASE_DIR/var/lib/apt/lists" \
-o "Dir::State::status=$BASE_DIR/var/lib/dpkg/status" \
-o "DPkg::Options::--admindir=$BASE_DIR/var/lib/dpkg" \
)
APTITUDE="aptitude ${APT_OPTIONS[@]}"
$APTITUDE update
$APTITUDE --download-only -y --allow-untrusted install "$@"
)
# We now have all required package files download into cache; put them
# into output directory.
ln -t "$PACKAGE_DIR/ubuntu" -vf var/cache/apt/archives/*.deb
# Create updated package index
( cd "$PACKAGE_DIR" && dpkg-scanpackages -m . | gzip -c >Packages.gz )
おそらくこれを使って同じことをするPythonプログラムを作成できますが、私の目的にはシェルスクリプトで十分です。