@@ -12,17 +12,30 @@ This performs a build inside a VM, with deterministic inputs and outputs. If th | |||
Install prereqs: | |||
sudo apt-get install python-vm-builder qemu-kvm apt-cacher | |||
sudo apt-get install apt-cacher | |||
sudo service apt-cacher start | |||
If you want to use kvm: | |||
sudo apt-get install python-vm-builder qemu-kvm | |||
or alternatively, lxc (no need for hardware support): | |||
sudo apt-get install debootstrap lxc | |||
Create the base VM for use in further builds (requires sudo, please review the script): | |||
bin/make-base-vm | |||
bin/make-base-vm --arch i386 | |||
or for lxc: | |||
bin/make-base-vm --lxc | |||
bin/make-base-vm --lxc --arch i386 | |||
Copy any additional build inputs into a directory named _inputs_. | |||
Then execute the build using a YAML description file (can be run as non-root): | |||
export USE_LXC=1 # LXC only | |||
bin/gbuild <package>.yml | |||
or if you need to specify a commit for one of the git remotes: |
@@ -22,7 +22,7 @@ def sanitize(str, where) | |||
end | |||
def sanitize_path(str, where) | |||
raise "unsanitary string in #{where}" if (str =~ /[^\w\/.-]/) | |||
raise "unsanitary string in #{where}" if (str =~ /[^\w\/.:-]/) | |||
str | |||
end | |||
@@ -34,6 +34,12 @@ def build_one_configuration(suite, arch, build_desc, reference_datetime) | |||
FileUtils.rm_f("var/build.log") | |||
bits = @bitness[arch] or raise "unknown architecture ${arch}" | |||
if ENV["USE_LXC"] | |||
ENV["LXC_ARCH"] = arch | |||
ENV["LXC_SUITE"] = suite | |||
end | |||
suitearch = "#{suite}-#{arch}" | |||
info "Stopping target if it is up" | |||
@@ -43,7 +49,7 @@ def build_one_configuration(suite, arch, build_desc, reference_datetime) | |||
unless @options[:skip_image] | |||
info "Making a new image copy" | |||
system! "cp base-#{suitearch}.qcow2 target-#{suitearch}.qcow2" | |||
system! "make-clean-vm --suite #{suite} --arch #{arch}" | |||
end | |||
info "Starting target" | |||
@@ -66,7 +72,7 @@ def build_one_configuration(suite, arch, build_desc, reference_datetime) | |||
build_desc["files"].each do |filename| | |||
filename = sanitize(filename, "files section") | |||
system! "cd inputs && copy-to-target #{@quiet_flag} #{filename} build/" | |||
system! "copy-to-target #{@quiet_flag} inputs/#{filename} build/" | |||
end | |||
info "Updating apt-get repository (log in var/install.log)" | |||
@@ -92,8 +98,14 @@ def build_one_configuration(suite, arch, build_desc, reference_datetime) | |||
script.puts "REFERENCE_TIME='#{ref_time}'" | |||
script.puts | |||
build_desc["remotes"].each do |remote| | |||
script.puts "git clone -q #{remote["url"]} build/#{remote["dir"]}" | |||
script.puts "(cd build/#{remote["dir"]} && git checkout -q #{remote["commit"]})" | |||
dir = sanitize(remote["dir"], remote["dir"]) | |||
if File.exist?("inputs/#{dir}") | |||
system!("cd inputs/#{dir} && git fetch") | |||
else | |||
system!("git clone -q #{sanitize_path(remote["url"], remote["url"])} inputs/#{dir}") | |||
end | |||
system! "copy-to-target #{@quiet_flag} inputs/#{dir} build/" | |||
script.puts "(cd build/#{dir} && git checkout -q #{remote["commit"]})" | |||
end | |||
script.puts "cd build" | |||
script.puts build_desc["script"] |
@@ -5,6 +5,7 @@ SUITE=lucid | |||
ARCH=amd64 | |||
MIRROR=http://${MIRROR_HOST:-127.0.0.1}:3142/archive.ubuntu.com/ubuntu | |||
SECURITY_MIRROR=http://${MIRROR_HOST:-127.0.0.1}:3142/security.ubuntu.com/ubuntu | |||
LXC=0 | |||
usage() { | |||
echo "Usage: ${0##*/} [OPTION]..." | |||
@@ -12,8 +13,9 @@ usage() { | |||
echo | |||
cat << EOF | |||
--help display this help and exit | |||
--suite=U build suite U instead of lucid | |||
--arch=A build architecture A (e.g. i386) instead of amd64 | |||
--suite U build suite U instead of lucid | |||
--arch A build architecture A (e.g. i386) instead of amd64 | |||
--lxc use lxc instead of kvm | |||
The MIRROR_HOST environment variable can be used to change the | |||
apt-cacher host. It should be something that the target VM can | |||
@@ -38,6 +40,10 @@ if [ $# != 0 ] ; then | |||
ARCH="$2" | |||
shift 2 | |||
;; | |||
--lxc) | |||
LXC=1 | |||
shift 1 | |||
;; | |||
--*) | |||
echo "unrecognized option $1" | |||
exit 1 | |||
@@ -56,21 +62,32 @@ if [ ! -e var/id_dsa ]; then | |||
fi | |||
OUT=base-$SUITE-$ARCH | |||
if [ -e $OUT.qcow2 ]; then | |||
echo $OUT.qcow2 already exists, please remove it first | |||
exit 1 | |||
fi | |||
rm -rf $OUT | |||
FLAVOUR=virtual | |||
if [ $ARCH = "amd64" -a $SUITE = "hardy" ]; then | |||
FLAVOUR=server | |||
fi | |||
sudo vmbuilder kvm ubuntu --arch=$ARCH --suite=$SUITE --addpkg=openssh-server,pciutils,build-essential,git-core,subversion --ssh-key=var/id_dsa.pub --ssh-user-key=var/id_dsa.pub --mirror=$MIRROR --security-mirror=$SECURITY_MIRROR --dest=$OUT --flavour=$FLAVOUR --firstboot=`pwd`/target-bin/bootstrap-fixup | |||
addpkg=openssh-server,pciutils,build-essential,git-core,subversion | |||
mv $OUT/*.qcow2 $OUT.qcow2 | |||
if [ $LXC = "0" ]; then | |||
if [ -e $OUT.qcow2 ]; then | |||
echo $OUT.qcow2 already exists, please remove it first | |||
exit 1 | |||
fi | |||
rm -rf $OUT | |||
sudo vmbuilder kvm ubuntu --arch=$ARCH --suite=$SUITE --addpkg=$addpkg --ssh-key=var/id_dsa.pub --ssh-user-key=var/id_dsa.pub --mirror=$MIRROR --security-mirror=$SECURITY_MIRROR --dest=$OUT --flavour=$FLAVOUR --firstboot=`pwd`/target-bin/bootstrap-fixup | |||
mv $OUT/*.qcow2 $OUT.qcow2 | |||
rm -rf $OUT | |||
else | |||
if [ -e $OUT ]; then | |||
echo $OUT already exists, please remove it first | |||
exit 1 | |||
fi | |||
rm -rf $OUT-root | |||
sudo debootstrap --include=$addpkg --arch=$ARCH $SUITE $OUT-root $MIRROR | |||
sudo target-bin/bootstrap-fixup $OUT-root | |||
fi | |||
rm -rf $OUT |
@@ -0,0 +1,32 @@ | |||
lxc.tty = 4 | |||
lxc.pts = 1024 | |||
lxc.rootfs = ROOTFS | |||
lxc.arch = ARCH | |||
lxc.cgroup.devices.deny = a | |||
# /dev/null and zero | |||
lxc.cgroup.devices.allow = c 1:3 rwm | |||
lxc.cgroup.devices.allow = c 1:5 rwm | |||
# consoles | |||
lxc.cgroup.devices.allow = c 5:1 rwm | |||
lxc.cgroup.devices.allow = c 5:0 rwm | |||
lxc.cgroup.devices.allow = c 4:0 rwm | |||
lxc.cgroup.devices.allow = c 4:1 rwm | |||
# /dev/{,u}random | |||
lxc.cgroup.devices.allow = c 1:9 rwm | |||
lxc.cgroup.devices.allow = c 1:8 rwm | |||
lxc.cgroup.devices.allow = c 136:* rwm | |||
lxc.cgroup.devices.allow = c 5:2 rwm | |||
# rtc | |||
lxc.cgroup.devices.allow = c 254:0 rwm | |||
# mounts points | |||
lxc.mount.entry=proc ROOTFS/proc proc nodev,noexec,nosuid 0 0 | |||
lxc.mount.entry=sysfs ROOTFS/sys sysfs defaults 0 0 | |||
# Container with network virtualized using a pre-configured bridge named br0 and | |||
# veth pair virtual network devices | |||
# On the host, run: ifconfig br0 up 10.0.2.2 | |||
lxc.network.type = veth | |||
lxc.network.flags = up | |||
lxc.network.link = br0 | |||
lxc.network.ipv4 = 10.0.2.5/24 |
@@ -0,0 +1,4 @@ | |||
#!/bin/bash | |||
wd=`pwd` | |||
sed "s;ROOTFS;$wd/target-$LXC_SUITE-$LXC_ARCH-root;;s;ARCH;$LXC_ARCH;g" < etc/lxc.config.in > var/lxc.config |
@@ -46,4 +46,9 @@ if [ $# = 0 ] ; then | |||
exit 1 | |||
fi | |||
scp $QUIET_FLAG -oConnectTimeout=5 -oNoHostAuthenticationForLocalhost=yes -i ${GITIAN_BASE:-.}/var/id_dsa -P $VM_SSH_PORT -r $TUSER@localhost:$1 $2 | |||
if [ -z "$USE_LXC" ]; then | |||
scp $QUIET_FLAG -oConnectTimeout=5 -oNoHostAuthenticationForLocalhost=yes -i ${GITIAN_BASE:-.}/var/id_dsa -P $VM_SSH_PORT -r $TUSER@localhost:$1 $2 | |||
else | |||
config-lxc | |||
sudo lxc-start -n gitian -f var/lxc.config -- sudo -i -u $TUSER tar -cf - "$1" | tar -C "$2" -xkf - | |||
fi |
@@ -46,4 +46,9 @@ if [ $# = 0 ] ; then | |||
exit 1 | |||
fi | |||
scp $QUIET_FLAG -oConnectTimeout=5 -oNoHostAuthenticationForLocalhost=yes -i ${GITIAN_BASE:-.}/var/id_dsa -P $VM_SSH_PORT $1 $TUSER@localhost:$2 | |||
if [ -z "$USE_LXC" ]; then | |||
scp $QUIET_FLAG -oConnectTimeout=5 -oNoHostAuthenticationForLocalhost=yes -i ${GITIAN_BASE:-.}/var/id_dsa -P $VM_SSH_PORT $1 $TUSER@localhost:$2 | |||
else | |||
config-lxc | |||
tar -C `dirname "$1"` -cf - `basename "$1"` | sudo lxc-start -n gitian -f var/lxc.config -- sudo -i -u $TUSER tar -C "$2" -xf - | |||
fi |
@@ -0,0 +1,53 @@ | |||
#!/bin/sh | |||
set -e | |||
SUITE=lucid | |||
ARCH=amd64 | |||
usage() { | |||
echo "Usage: ${0##*/} [OPTION]..." | |||
echo "Make a clean copy of the base client." | |||
echo | |||
cat << EOF | |||
--help display this help and exit | |||
--suite U build suite U instead of lucid | |||
--arch A build architecture A (e.g. i386) instead of amd64 | |||
EOF | |||
} | |||
if [ $# != 0 ] ; then | |||
while true ; do | |||
case "$1" in | |||
--help|-h) | |||
usage | |||
exit 0 | |||
;; | |||
--suite|-s) | |||
SUITE="$2" | |||
shift 2 | |||
;; | |||
--arch|-a) | |||
ARCH="$2" | |||
shift 2 | |||
;; | |||
--*) | |||
echo "unrecognized option $1" | |||
exit 1 | |||
;; | |||
*) | |||
break | |||
;; | |||
esac | |||
done | |||
fi | |||
BASE=base-$SUITE-$ARCH-root | |||
OUT=target-$SUITE-$ARCH-root | |||
if [ -z "$USE_LXC" ]; then | |||
cp $BASE.qcow2 $OUT.qcow2 | |||
else | |||
sudo rm -rf $OUT | |||
sudo cp -a $BASE $OUT | |||
on-target -u root useradd -m ubuntu | |||
fi |
@@ -41,4 +41,13 @@ fi | |||
# exit 1 | |||
#fi | |||
ssh -oConnectTimeout=5 -oNoHostAuthenticationForLocalhost=yes -i ${GITIAN_BASE:-.}/var/id_dsa -p $VM_SSH_PORT $TUSER@localhost $* | |||
if [ -z "$USE_LXC" ]; then | |||
ssh -oConnectTimeout=5 -oNoHostAuthenticationForLocalhost=yes -i ${GITIAN_BASE:-.}/var/id_dsa -p $VM_SSH_PORT $TUSER@localhost $* | |||
else | |||
config-lxc | |||
if [ $TUSER = "root" ]; then | |||
sudo lxc-start -n gitian -f var/lxc.config -- $* | |||
else | |||
sudo lxc-start -n gitian -f var/lxc.config -- sudo -i -u $TUSER $* | |||
fi | |||
fi |
@@ -5,8 +5,11 @@ | |||
ARCH=qemu$1 | |||
SUFFIX=$2 | |||
kvm -cpu $ARCH -m ${VMEM:-2000} -smp ${NPROCS:-2} -drive file=target-$SUFFIX.qcow2 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:$VM_SSH_PORT-:22 -vnc 127.0.0.1:16 > var/target.log 2>&1 & | |||
echo $! > var/target.pid | |||
wait | |||
rm var/target.pid | |||
if [ -z "$USE_LXC" ]; then | |||
kvm -cpu $ARCH -m ${VMEM:-2000} -smp ${NPROCS:-2} -drive file=target-$SUFFIX.qcow2 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:$VM_SSH_PORT-:22 -vnc 127.0.0.1:16 > var/target.log 2>&1 & | |||
echo $! > var/target.pid | |||
wait | |||
rm var/target.pid | |||
else | |||
true #sudo lxc-start -n gitian -c var/target.log -f lxc.config | |||
fi |
@@ -1,14 +1,18 @@ | |||
#!/bin/sh | |||
if [ ! -e var/target.pid ]; then exit; fi | |||
if [ -z "$USE_LXC" ]; then | |||
if [ ! -e var/target.pid ]; then exit; fi | |||
on-target -u root halt | |||
sleep 5 | |||
on-target -u root halt | |||
sleep 5 | |||
if [ ! -e var/target.pid ]; then exit; fi | |||
sleep 5 | |||
if [ ! -e var/target.pid ]; then exit; fi | |||
sleep 5 | |||
if [ ! -e var/target.pid ]; then exit; fi | |||
if [ ! -e var/target.pid ]; then exit; fi | |||
echo Killing target since it did not shutdown within 10 seconds | |||
kill `cat var/target.pid` | |||
echo Killing target since it did not shutdown within 10 seconds | |||
kill `cat var/target.pid` | |||
else | |||
true | |||
fi |
@@ -2,4 +2,4 @@ | |||
set -e | |||
sed -i -e 's/127.0.0.1:/10.0.2.2:/' $1/etc/apt/sources.list | |||
echo 'deb http://10.0.2.2:3142/archive.ubuntu.com/ubuntu lucid main universe' > $1/etc/apt/sources.list |