Browse Source

First pass lxc support

git-archive
devrandom 11 years ago
parent
commit
28bb421156
  1. 15
      README.md
  2. 22
      bin/gbuild
  3. 41
      bin/make-base-vm
  4. 32
      etc/lxc.config.in
  5. 4
      libexec/config-lxc
  6. 7
      libexec/copy-from-target
  7. 7
      libexec/copy-to-target
  8. 53
      libexec/make-clean-vm
  9. 11
      libexec/on-target
  10. 13
      libexec/start-target
  11. 20
      libexec/stop-target
  12. 2
      target-bin/bootstrap-fixup

15
README.md

@ -12,17 +12,30 @@ This performs a build inside a VM, with deterministic inputs and outputs. If th @@ -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
bin/gbuild

@ -22,7 +22,7 @@ def sanitize(str, where) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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"]

41
bin/make-base-vm

@ -5,6 +5,7 @@ SUITE=lucid @@ -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() { @@ -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 @@ -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 @@ -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

32
etc/lxc.config.in

@ -0,0 +1,32 @@ @@ -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

4
libexec/config-lxc

@ -0,0 +1,4 @@ @@ -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

7
libexec/copy-from-target

@ -46,4 +46,9 @@ if [ $# = 0 ] ; then @@ -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

7
libexec/copy-to-target

@ -46,4 +46,9 @@ if [ $# = 0 ] ; then @@ -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

53
libexec/make-clean-vm

@ -0,0 +1,53 @@ @@ -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

11
libexec/on-target

@ -41,4 +41,13 @@ 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

13
libexec/start-target

@ -5,8 +5,11 @@ @@ -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

20
libexec/stop-target

@ -1,14 +1,18 @@ @@ -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
target-bin/bootstrap-fixup

@ -2,4 +2,4 @@ @@ -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

Loading…
Cancel
Save