bdisk/docs/manual/faq/LONGTIME.adoc
2016-12-29 15:04:47 -05:00

5.7 KiB
Raw Permalink Blame History

Why does building take so long?

This typically occurs when youre building from within a LiveCD/LiveUSB situation, in a VM/container/etc., or on a headless server. If this is the case, you may run into what appears to be "stalling", especially while keys are generating for the chroots. Thankfully, there is an easy fix. You can install haveged and run it (this can be done safely while a build is executing). This will show an immediate and non-negligible improvement for the above contexts. If you have extra processing power to throw at the build process (or are using a dedicated build box) as well, I recommend enabling i_am_a_racecar. BDisk will then be more aggressive with its resource consumption.

Running a local mirror

Keep in mind also that the more packages you opt to install, the longer the build process will take. This process will also use quite a fair bit of bandwidth. If you plan on building regular images (e.g. nightly builds, etc.) or are undergoing some custom change testing, I recommend running a private repository mirror on-site. This will not store AUR packages, as those will still be fetched and built (documentation on working around this is TODO) but setting up a local mirror is quite quick and easy.

First, youll need at least 70Gb of free disk space. Lets say our repository clone will be at /srv/repo/arch/.

Youll also need to find an Arch mirror, ideally one close to you that is up-to-date. The mirrorlist generator and mirror list will assist you here greatly.

Note
Youll need to find a mirror that supports rsync.
Tip
You can use ANY distro to run a repository mirror, as long as it has rsync installed!

Set up the sync

Create a script and mark it as executable with the following content:

#!/bin/bash
SOURCE='rsync://your.mirror.here/archlinux'
DEST='/srv/repo/arch'
LCK_FLE='/var/run/repo-sync.lck'
PATH='/usr/bin'
if [ -e "${LCK_FLE}" ] ; then
	OTHER_PID=$(cat ${LCK_FLE})
	echo "Another instance already running: ${OTHER_PID}"
	exit 1
fi
# If e.g. /srv/repo is a mountpoint, uncomment below.
#findmnt /srv/repo > /dev/null 2>&1
#if [[ "${?}" -ne '0' ]];
#then
#	echo "External storage not mounted!"
#	exit 1
#fi
echo $$ > "${LCK_FLE}"
rsync -rvtlH --delete-after --delay-updates --safe-links --max-delete=1000 ${SOURCE}/. ${DEST}/. >> /var/log/arch.repo.sync 2>&1
date +%s > ${DEST}/lastsync
rm -f "${LCK_FLE}"

Assuming you want to run the sync script every 6 hours and it is located at /root/bin/arch.repo.clone.sh, this is the cron entry you would use (crontab -e):

0    */6  *   *   * /root/bin/arch.repo.clone.sh > /dev/null 2>&1

The first sync can take quite a while, but subsequent runs shouldnt take more than five minutes or so.

Configuring the local mirror

Youll need a way to serve this local mirror in a way pacman can understand. Luckily, its fairly easy. I recommend using nginx as its available by default in many operating systems. You can of course use others such as lighttpd, apache/httpd, etc. For the example configuration here, were going to use an nginx configuration file.

server {
listen [::]:80;
access_log /var/log/nginx/repo.access.log main;
error_log /var/log/nginx/repo.error.log;
#error_log /var/log/nginx/repo.error.log debug;

autoindex on;

root /srv/repo/arch;

}

The configuration may vary according to your distributions provided nginx default configuration, but youll want this configuration to be served as the default (or set an appropriate server_name directive which you would then use in <basedir>/extra/pre-build.d/etc/pacman.d/mirrorlist).

Configuring BDisk

Youll then want to configure BDisks chroots to use your local mirror first. However, when doing so you run into an issuein the built image, install operations will take longer than they need to because the local mirror likely wont be available! This is a small issue as its unexpected that youll need to install software within the live environment, but Ive run into cases where it was a necessity once or twice.

There is an easy workaround if youre using libvirtyou can simply tell your build VM to resolve to the IP address of the box that is running the mirror for the same FQDN that the "preferred" "real" mirror on the Internet is and set that mirror at the top of <basedir>/extra/pre-build.d/etc/pacman.d/mirrorlist. However, thats not always feasible- most notably if youre building on a physical box and its the same host as the repository clone. In that case you can set the specific local resolutione.g. http://127.0.0.1/at the top of <basedir>/extra/pre-build.d/etc/pacman.d/mirrorlist and then set a mirrorlist WITHOUT that entry in <basedir>/overlay/etc/pacman.d/mirrorlist. For more information on using these type of overrides, see [advanced_customization].

If youre using the libvirt workaround, remember to configure nginx (or whatever youre using) with a virtual host and location block that matches the "real", upstream mirror. In our example below, we use http://mirror.us.leaseweb.net/archlinux as the mirror.

server {
listen [::]:80;
access_log /var/log/nginx/repo.access.log main;
error_log /var/log/nginx/repo.error.log;
#error_log /var/log/nginx/repo.error.log debug;

server_name mirror.us.leaseweb.net;

autoindex on;

root /srv/repo/arch;

location /archlinux {
	autoindex on;
	rewrite ^/archlinux(/.*)$ /$1;
	}

}