2015-03-22 14:04:46 +00:00
|
|
|
#!/bin/bash
|
|
|
|
#
|
|
|
|
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
|
|
# not use this file except in compliance with the License. You may obtain
|
|
|
|
# a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
# License for the specific language governing permissions and limitations
|
|
|
|
# under the License.
|
|
|
|
#
|
|
|
|
if [ "${DIB_DEBUG_TRACE:-0}" -gt 0 ]; then
|
|
|
|
set -x
|
|
|
|
fi
|
|
|
|
set -eu
|
|
|
|
set -o pipefail
|
|
|
|
|
|
|
|
if [ -f ${TARGET_ROOT}/.extra_settings ] ; then
|
|
|
|
. ${TARGET_ROOT}/.extra_settings
|
|
|
|
fi
|
|
|
|
ARCH=${ARCH:-x86_64}
|
|
|
|
if [ $ARCH = amd64 ]; then
|
|
|
|
ARCH=x86_64
|
|
|
|
fi
|
|
|
|
# Calling elements will need to set DISTRO_NAME and DIB_RELEASE
|
|
|
|
DIB_YUMCHROOT_EXTRA_ARGS=${DIB_YUMCHROOT_EXTRA_ARGS:-}
|
|
|
|
YUMCHROOT_TARBALL=$DIB_IMAGE_CACHE/yumchroot-${DISTRO_NAME}-${DIB_RELEASE}-${ARCH}.tar.gz
|
|
|
|
# TODO Maybe deal with DIB_DISTRIBUTION_MIRROR
|
|
|
|
http_proxy=${http_proxy:-}
|
2015-10-15 18:16:44 +00:00
|
|
|
YUM=${YUM:-yum}
|
2015-03-22 14:04:46 +00:00
|
|
|
|
2015-09-24 04:55:48 +00:00
|
|
|
WORKING=$(mktemp --tmpdir=${TMP_DIR:-/tmp} -d)
|
|
|
|
EACTION="rm -r $WORKING"
|
|
|
|
trap "$EACTION" EXIT
|
2015-03-22 14:04:46 +00:00
|
|
|
|
2015-09-24 04:55:48 +00:00
|
|
|
YUM_CACHE=$DIB_IMAGE_CACHE/yum
|
2015-10-23 04:17:18 +00:00
|
|
|
mkdir -p $YUM_CACHE
|
2015-03-22 14:04:46 +00:00
|
|
|
|
Fixup RPM db path when building Fedora on Ubuntu
On Debian/Ubuntu installs of RPM, /usr/lib/rpm/macros sets
%_dbpath %(echo $HOME/.rpmdb)
which makes quite a bit of sense, because RPM is not the system
packager and thus RPM is setup to install things into a hierarchy in
the users homedir.
However, this messes things up when building a Fedora chroot on an
Ubuntu platform.
We use RPM & yum from the base-system to bootstrap the Fedora chroot.
While both obey --root flags, they still pick up the %_dbpath macro
and so end up creating the RPM database in <chroot>/home/user/.rpmdb
After we have bootstrapped yum/dnf, we execute further installation
commands from inside the chroot -- where we now have the Fedora
version of /usr/lib/rpm/macros and hence have _dbpath set to
/var/lib/rpm -- except there is no rpm database there.
Should anyone be finding this in the future, the actual issue that
appears is
$ sudo chroot /opt/dib_tmp/image.b6B5S3f6/mnt dnf makecache
Error: Failed to synchronize cache for repo 'fedora' from \
'https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=x86_64': \
Cannot prepare internal mirrorlist: file "repomd.xml" was not found in metalink
Note the issue there is that $releasever is not expanded, because the
rpmdb where this info is kept is not populated.
The trick is to make sure we override this value when using the host
rpm/yum to setup the chroot. The bare rpm calls, which we use to
install the repos, have a --dbpath argument where we can override
this. yum does not however, so we override this in the global
~/.rpmmacros while we are installing the packaging tools and
dependencies into the chroot.
Copious comments are included, because this is super-confusing.
Change-Id: I20801150ea02d1c64f118eb969fb2aec473476f7
2015-10-23 04:42:00 +00:00
|
|
|
# Note, on Debian/Ubuntu, %_dbpath is set in the RPM macros as
|
|
|
|
# ${HOME}/.rpmdb/ -- this makes sense as RPM isn't the system
|
|
|
|
# packager. This path is relative to the "--root" argument
|
|
|
|
_RPM="rpm --dbpath=/var/lib/rpm"
|
|
|
|
|
2015-09-24 04:55:48 +00:00
|
|
|
# install the [fedora|centos]-[release|repo] packages inside the
|
|
|
|
# chroot, which are needed to bootstrap yum/dnf
|
|
|
|
#
|
|
|
|
# note this runs outside the chroot, where we're assuming the platform
|
|
|
|
# has yum/yumdownloader
|
|
|
|
function _install_repos {
|
2015-03-22 14:04:46 +00:00
|
|
|
yumdownloader \
|
2015-09-24 04:55:48 +00:00
|
|
|
--releasever=$DIB_RELEASE \
|
|
|
|
--setopt=reposdir=$TMP_HOOKS_PATH/yum.repos.d \
|
|
|
|
--destdir=$WORKING \
|
2015-03-22 14:04:46 +00:00
|
|
|
${DISTRO_NAME}-release
|
2015-09-24 04:55:48 +00:00
|
|
|
|
|
|
|
# after fedora21, this is split into into a separate -repos
|
|
|
|
# package
|
2015-03-22 14:04:46 +00:00
|
|
|
if [ $DISTRO_NAME = fedora ] ; then
|
|
|
|
yumdownloader \
|
2015-09-24 04:55:48 +00:00
|
|
|
--releasever=$DIB_RELEASE \
|
|
|
|
--setopt=reposdir=$TMP_HOOKS_PATH/yum.repos.d \
|
|
|
|
--destdir=$WORKING \
|
2015-03-22 14:04:46 +00:00
|
|
|
${DISTRO_NAME}-repos
|
|
|
|
fi
|
2015-09-24 00:14:18 +00:00
|
|
|
|
|
|
|
# --nodeps works around these wanting /bin/sh in some fedora
|
|
|
|
# releases, see rhbz#1265873
|
Fixup RPM db path when building Fedora on Ubuntu
On Debian/Ubuntu installs of RPM, /usr/lib/rpm/macros sets
%_dbpath %(echo $HOME/.rpmdb)
which makes quite a bit of sense, because RPM is not the system
packager and thus RPM is setup to install things into a hierarchy in
the users homedir.
However, this messes things up when building a Fedora chroot on an
Ubuntu platform.
We use RPM & yum from the base-system to bootstrap the Fedora chroot.
While both obey --root flags, they still pick up the %_dbpath macro
and so end up creating the RPM database in <chroot>/home/user/.rpmdb
After we have bootstrapped yum/dnf, we execute further installation
commands from inside the chroot -- where we now have the Fedora
version of /usr/lib/rpm/macros and hence have _dbpath set to
/var/lib/rpm -- except there is no rpm database there.
Should anyone be finding this in the future, the actual issue that
appears is
$ sudo chroot /opt/dib_tmp/image.b6B5S3f6/mnt dnf makecache
Error: Failed to synchronize cache for repo 'fedora' from \
'https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=x86_64': \
Cannot prepare internal mirrorlist: file "repomd.xml" was not found in metalink
Note the issue there is that $releasever is not expanded, because the
rpmdb where this info is kept is not populated.
The trick is to make sure we override this value when using the host
rpm/yum to setup the chroot. The bare rpm calls, which we use to
install the repos, have a --dbpath argument where we can override
this. yum does not however, so we override this in the global
~/.rpmmacros while we are installing the packaging tools and
dependencies into the chroot.
Copious comments are included, because this is super-confusing.
Change-Id: I20801150ea02d1c64f118eb969fb2aec473476f7
2015-10-23 04:42:00 +00:00
|
|
|
sudo $_RPM --root $TARGET_ROOT --nodeps -ivh $WORKING/*rpm
|
2015-09-24 04:55:48 +00:00
|
|
|
}
|
2015-03-22 14:04:46 +00:00
|
|
|
|
2015-09-24 04:55:48 +00:00
|
|
|
# _install_pkg_manager packages...
|
|
|
|
#
|
|
|
|
# install the package manager packages. This is done outside the chroot
|
|
|
|
# and with yum from the build system.
|
|
|
|
# TODO: one day build systems will be dnf only, but we don't handle
|
|
|
|
# that right now
|
|
|
|
function _install_pkg_manager {
|
|
|
|
# Install into the chroot, using the gpg keys from the release
|
|
|
|
# rpm's installed in the chroot
|
|
|
|
sudo sed -i "s,/etc/pki/rpm-gpg,$TARGET_ROOT/etc/pki/rpm-gpg,g" \
|
|
|
|
$TARGET_ROOT/etc/yum.repos.d/*repo
|
2015-03-22 14:04:46 +00:00
|
|
|
|
Fixup RPM db path when building Fedora on Ubuntu
On Debian/Ubuntu installs of RPM, /usr/lib/rpm/macros sets
%_dbpath %(echo $HOME/.rpmdb)
which makes quite a bit of sense, because RPM is not the system
packager and thus RPM is setup to install things into a hierarchy in
the users homedir.
However, this messes things up when building a Fedora chroot on an
Ubuntu platform.
We use RPM & yum from the base-system to bootstrap the Fedora chroot.
While both obey --root flags, they still pick up the %_dbpath macro
and so end up creating the RPM database in <chroot>/home/user/.rpmdb
After we have bootstrapped yum/dnf, we execute further installation
commands from inside the chroot -- where we now have the Fedora
version of /usr/lib/rpm/macros and hence have _dbpath set to
/var/lib/rpm -- except there is no rpm database there.
Should anyone be finding this in the future, the actual issue that
appears is
$ sudo chroot /opt/dib_tmp/image.b6B5S3f6/mnt dnf makecache
Error: Failed to synchronize cache for repo 'fedora' from \
'https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=x86_64': \
Cannot prepare internal mirrorlist: file "repomd.xml" was not found in metalink
Note the issue there is that $releasever is not expanded, because the
rpmdb where this info is kept is not populated.
The trick is to make sure we override this value when using the host
rpm/yum to setup the chroot. The bare rpm calls, which we use to
install the repos, have a --dbpath argument where we can override
this. yum does not however, so we override this in the global
~/.rpmmacros while we are installing the packaging tools and
dependencies into the chroot.
Copious comments are included, because this is super-confusing.
Change-Id: I20801150ea02d1c64f118eb969fb2aec473476f7
2015-10-23 04:42:00 +00:00
|
|
|
# See notes on $_RPM variable -- we need to override the
|
|
|
|
# $HOME-based dbpath set on debian/ubuntu here. Unfortunately,
|
|
|
|
# yum does not have a way to override rpm macros from the command
|
|
|
|
# line. So we modify the user's ~/.rpmmacros to set %_dbpath back
|
|
|
|
# to "/var/lib/rpm" (note, this is taken relative to the
|
|
|
|
# --installroot).
|
|
|
|
#
|
|
|
|
# Also note, we only want this done around this call -- this is
|
|
|
|
# the only place we are using yum outside the chroot, and hence
|
|
|
|
# picking up the base-system's default rpm macros. For example,
|
|
|
|
# the yumdownloader calls above in _install_repos want to use
|
|
|
|
# ~/.rpmdb/ ... there is nothing in the build-system /var/lib/rpm!
|
2015-12-01 20:26:26 +00:00
|
|
|
#
|
|
|
|
# Another issue we hit is having to set --releasedir here. yum
|
|
|
|
# determines $releasevar based on (more or less) "rpm -q
|
|
|
|
# --whatprovides $distroverpkg". By default, this is
|
|
|
|
# "redhat-release" (fedora-release provides redhat-release) but
|
|
|
|
# some platforms like CentOS override it in /etc/yum.conf (to
|
|
|
|
# centos-release in their case). You can't override this (see
|
|
|
|
# [1]), but setting --releasever works around this.
|
|
|
|
#
|
|
|
|
# [1] https://bugzilla.redhat.com/show_bug.cgi?id=1287333
|
Fixup RPM db path when building Fedora on Ubuntu
On Debian/Ubuntu installs of RPM, /usr/lib/rpm/macros sets
%_dbpath %(echo $HOME/.rpmdb)
which makes quite a bit of sense, because RPM is not the system
packager and thus RPM is setup to install things into a hierarchy in
the users homedir.
However, this messes things up when building a Fedora chroot on an
Ubuntu platform.
We use RPM & yum from the base-system to bootstrap the Fedora chroot.
While both obey --root flags, they still pick up the %_dbpath macro
and so end up creating the RPM database in <chroot>/home/user/.rpmdb
After we have bootstrapped yum/dnf, we execute further installation
commands from inside the chroot -- where we now have the Fedora
version of /usr/lib/rpm/macros and hence have _dbpath set to
/var/lib/rpm -- except there is no rpm database there.
Should anyone be finding this in the future, the actual issue that
appears is
$ sudo chroot /opt/dib_tmp/image.b6B5S3f6/mnt dnf makecache
Error: Failed to synchronize cache for repo 'fedora' from \
'https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=x86_64': \
Cannot prepare internal mirrorlist: file "repomd.xml" was not found in metalink
Note the issue there is that $releasever is not expanded, because the
rpmdb where this info is kept is not populated.
The trick is to make sure we override this value when using the host
rpm/yum to setup the chroot. The bare rpm calls, which we use to
install the repos, have a --dbpath argument where we can override
this. yum does not however, so we override this in the global
~/.rpmmacros while we are installing the packaging tools and
dependencies into the chroot.
Copious comments are included, because this is super-confusing.
Change-Id: I20801150ea02d1c64f118eb969fb2aec473476f7
2015-10-23 04:42:00 +00:00
|
|
|
(
|
|
|
|
flock -w 1200 9 || die "Can not lock .rpmmacros"
|
|
|
|
echo "%_dbpath /var/lib/rpm" >> $HOME/.rpmmacros
|
|
|
|
sudo -E yum -y \
|
2015-03-22 14:04:46 +00:00
|
|
|
--setopt=cachedir=$YUM_CACHE/$ARCH/$DIB_RELEASE \
|
|
|
|
--setopt=reposdir=$TARGET_ROOT/etc/yum.repos.d \
|
2015-12-01 20:26:26 +00:00
|
|
|
--releasever=$DIB_RELEASE \
|
2015-03-22 14:04:46 +00:00
|
|
|
--installroot $TARGET_ROOT \
|
Fixup RPM db path when building Fedora on Ubuntu
On Debian/Ubuntu installs of RPM, /usr/lib/rpm/macros sets
%_dbpath %(echo $HOME/.rpmdb)
which makes quite a bit of sense, because RPM is not the system
packager and thus RPM is setup to install things into a hierarchy in
the users homedir.
However, this messes things up when building a Fedora chroot on an
Ubuntu platform.
We use RPM & yum from the base-system to bootstrap the Fedora chroot.
While both obey --root flags, they still pick up the %_dbpath macro
and so end up creating the RPM database in <chroot>/home/user/.rpmdb
After we have bootstrapped yum/dnf, we execute further installation
commands from inside the chroot -- where we now have the Fedora
version of /usr/lib/rpm/macros and hence have _dbpath set to
/var/lib/rpm -- except there is no rpm database there.
Should anyone be finding this in the future, the actual issue that
appears is
$ sudo chroot /opt/dib_tmp/image.b6B5S3f6/mnt dnf makecache
Error: Failed to synchronize cache for repo 'fedora' from \
'https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=x86_64': \
Cannot prepare internal mirrorlist: file "repomd.xml" was not found in metalink
Note the issue there is that $releasever is not expanded, because the
rpmdb where this info is kept is not populated.
The trick is to make sure we override this value when using the host
rpm/yum to setup the chroot. The bare rpm calls, which we use to
install the repos, have a --dbpath argument where we can override
this. yum does not however, so we override this in the global
~/.rpmmacros while we are installing the packaging tools and
dependencies into the chroot.
Copious comments are included, because this is super-confusing.
Change-Id: I20801150ea02d1c64f118eb969fb2aec473476f7
2015-10-23 04:42:00 +00:00
|
|
|
install $@
|
|
|
|
sed -i '$ d' $HOME/.rpmmacros
|
|
|
|
) 9>$HOME/.rpmmacros.dib.lock
|
|
|
|
rm $HOME/.rpmmacros.dib.lock
|
2015-09-24 04:55:48 +00:00
|
|
|
# Set gpg path back because subsequent actions will take place in
|
|
|
|
# the chroot
|
|
|
|
sudo sed -i "s,$TARGET_ROOT/etc/pki/rpm-gpg,/etc/pki/rpm-gpg,g" \
|
|
|
|
$TARGET_ROOT/etc/yum.repos.d/*repo
|
|
|
|
}
|
2015-03-22 14:04:46 +00:00
|
|
|
|
2015-09-24 04:55:48 +00:00
|
|
|
if [ -n "$DIB_OFFLINE" -o -n "${DIB_YUMCHROOT_USE_CACHE:-}" ] && [ -f $YUMCHROOT_TARBALL ] ; then
|
|
|
|
echo $YUMCHROOT_TARBALL found in cache. Using.
|
|
|
|
sudo tar -C $TARGET_ROOT --numeric-owner -xzf $YUMCHROOT_TARBALL
|
|
|
|
else
|
2015-10-27 04:10:30 +00:00
|
|
|
# Note this is not usually done for root.d elements (see
|
|
|
|
# lib/common-functions:mount_proc_dev_sys) but it's important that
|
|
|
|
# we have things like /dev/urandom around inside the chroot for
|
|
|
|
# the rpm [pre|post]inst scripts within the packages.
|
|
|
|
sudo mkdir -p $TARGET_ROOT/proc $TARGET_ROOT/dev $TARGET_ROOT/sys
|
|
|
|
sudo mount -t proc none $TARGET_ROOT/proc
|
|
|
|
sudo mount --bind /dev $TARGET_ROOT/dev
|
|
|
|
sudo mount --bind /dev/pts $TARGET_ROOT/dev/pts
|
|
|
|
sudo mount -t sysfs none $TARGET_ROOT/sys
|
|
|
|
|
2015-09-24 04:55:48 +00:00
|
|
|
# initalize rpmdb
|
|
|
|
sudo mkdir -p $TARGET_ROOT/var/lib/rpm
|
Fixup RPM db path when building Fedora on Ubuntu
On Debian/Ubuntu installs of RPM, /usr/lib/rpm/macros sets
%_dbpath %(echo $HOME/.rpmdb)
which makes quite a bit of sense, because RPM is not the system
packager and thus RPM is setup to install things into a hierarchy in
the users homedir.
However, this messes things up when building a Fedora chroot on an
Ubuntu platform.
We use RPM & yum from the base-system to bootstrap the Fedora chroot.
While both obey --root flags, they still pick up the %_dbpath macro
and so end up creating the RPM database in <chroot>/home/user/.rpmdb
After we have bootstrapped yum/dnf, we execute further installation
commands from inside the chroot -- where we now have the Fedora
version of /usr/lib/rpm/macros and hence have _dbpath set to
/var/lib/rpm -- except there is no rpm database there.
Should anyone be finding this in the future, the actual issue that
appears is
$ sudo chroot /opt/dib_tmp/image.b6B5S3f6/mnt dnf makecache
Error: Failed to synchronize cache for repo 'fedora' from \
'https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=x86_64': \
Cannot prepare internal mirrorlist: file "repomd.xml" was not found in metalink
Note the issue there is that $releasever is not expanded, because the
rpmdb where this info is kept is not populated.
The trick is to make sure we override this value when using the host
rpm/yum to setup the chroot. The bare rpm calls, which we use to
install the repos, have a --dbpath argument where we can override
this. yum does not however, so we override this in the global
~/.rpmmacros while we are installing the packaging tools and
dependencies into the chroot.
Copious comments are included, because this is super-confusing.
Change-Id: I20801150ea02d1c64f118eb969fb2aec473476f7
2015-10-23 04:42:00 +00:00
|
|
|
sudo $_RPM --root $TARGET_ROOT --initdb
|
2015-09-24 04:55:48 +00:00
|
|
|
|
|
|
|
# this makes sure that running yum/dnf in the chroot it can get
|
|
|
|
# out to download stuff
|
|
|
|
sudo mkdir $TARGET_ROOT/etc
|
2015-03-22 14:04:46 +00:00
|
|
|
sudo cp /etc/resolv.conf $TARGET_ROOT/etc/resolv.conf
|
|
|
|
|
2015-09-24 04:55:48 +00:00
|
|
|
# Bind mount the external yum cache inside the chroot. Same logic
|
|
|
|
# as in the yum element to provide for yum caching copied here
|
|
|
|
# because the sequencing is wrong otherwise
|
2015-03-22 14:04:46 +00:00
|
|
|
sudo mkdir -p $TMP_MOUNT_PATH/tmp/yum
|
|
|
|
sudo mount --bind $YUM_CACHE $TMP_MOUNT_PATH/tmp/yum
|
2015-09-24 04:55:48 +00:00
|
|
|
|
|
|
|
_install_repos
|
|
|
|
|
|
|
|
if [ $DIB_RELEASE -ge 22 ]; then
|
|
|
|
# install dnf for >= f22
|
|
|
|
_install_pkg_manager dnf dnf-plugins-core yum
|
|
|
|
else
|
|
|
|
_install_pkg_manager yum
|
|
|
|
fi
|
|
|
|
|
|
|
|
# bootstrap the environment within the chroot
|
2015-10-16 16:32:35 +00:00
|
|
|
sudo -E chroot $TARGET_ROOT ${YUM} makecache
|
|
|
|
sudo -E chroot $TARGET_ROOT ${YUM} -y \
|
2015-03-22 14:04:46 +00:00
|
|
|
--setopt=cachedir=/tmp/yum/$ARCH/$DIB_RELEASE \
|
|
|
|
install passwd findutils sudo util-linux-ng
|
|
|
|
|
2015-09-24 04:55:48 +00:00
|
|
|
# cleanup
|
2015-10-27 04:10:30 +00:00
|
|
|
# TODO : move this into a exit trap; and reconsider how
|
|
|
|
# this integrates with the global exit cleanup path.
|
2015-09-24 04:55:48 +00:00
|
|
|
sudo rm $TARGET_ROOT/etc/resolv.conf
|
|
|
|
sudo umount $TMP_MOUNT_PATH/tmp/yum
|
2015-10-27 04:10:30 +00:00
|
|
|
sudo umount $TARGET_ROOT/proc
|
|
|
|
sudo umount $TARGET_ROOT/dev/pts
|
|
|
|
sudo umount $TARGET_ROOT/dev
|
|
|
|
sudo umount $TARGET_ROOT/sys
|
2015-09-24 04:55:48 +00:00
|
|
|
|
2015-03-22 14:04:46 +00:00
|
|
|
# RPM doesn't know whether files have been changed since install
|
|
|
|
# At this point though, we know for certain that we have changed no
|
|
|
|
# config files, so anything marked .rpmnew is just a bug.
|
|
|
|
for newfile in $(sudo find $TARGET_ROOT -type f -name '*rpmnew') ; do
|
|
|
|
sudo mv $newfile $(echo $newfile | sed 's/.rpmnew$//')
|
|
|
|
done
|
|
|
|
|
|
|
|
echo Caching result in $YUMCHROOT_TARBALL
|
2015-09-24 04:55:48 +00:00
|
|
|
sudo tar --numeric-owner \
|
|
|
|
-C $TARGET_ROOT \
|
|
|
|
-zcf $YUMCHROOT_TARBALL --exclude='./tmp/*' .
|
2015-03-22 14:04:46 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
sudo rm -f ${TARGET_ROOT}/.extra_settings
|