You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

make-base-vm 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #!/bin/sh
  2. set -e
  3. DISTRO=ubuntu
  4. SUITE=xenial
  5. ARCH=amd64
  6. LXC=0
  7. VBOX=0
  8. DOCKER=0
  9. DOCKER_IMAGE_HASH=""
  10. usage() {
  11. echo "Usage: ${0##*/} [OPTION]..."
  12. echo "Make a base client."
  13. echo
  14. cat << EOF
  15. --help display this help and exit
  16. --distro D build distro D (e.g. debian) instead of ubuntu
  17. --suite U build suite U instead of xenial
  18. --arch A build architecture A (e.g. i386) instead of amd64
  19. --lxc use lxc instead of kvm
  20. --vbox use VirtualBox instead of kvm
  21. --docker use docker instead of kvm
  22. --docker-image-hash D digest of the docker image to build from
  23. The MIRROR_HOST environment variable can be used to change the
  24. apt-cacher host. It should be something that both the host and the
  25. target VM can reach. It may be set to 127.0.0.1, in which case it will be
  26. changed to 10.0.2.2 on the guest (or GITIAN_HOST_IP if it is defined)
  27. 10.0.2.2 is the host IP as visible from the guest under qemu networking.
  28. The DEBOOTSTRAP_DIR (but also GITIAN_SUDO_USE_DEBOOTSTRAP_DIR, see below!)
  29. environment variable can be set to select a directory
  30. that will contain data like in "/usr/share/debootstrap/". This allows user to
  31. make a copy of this files to some local dir and modify them locally:
  32. e.g. set env variable "DEBOOTSTRAP_DIR=./mydeboot/", then copy or link
  33. system's version of files there, and modify them there
  34. (e.g. copy your debootstrap-script file "xenial" to "./mydeboot/scripts/").
  35. Set env GITIAN_SUDO_USE_DEBOOTSTRAP_DIR="yes" to allow sudo for debootstrap
  36. to use flags like --preserve-env that are required for DEBOOTSTRAP_DIR to work.
  37. It must be equal string "yes".
  38. This is done as separate variable to make it clear that we modify sudo
  39. behaviour here regarding security (though anyway env is cleared with
  40. whitelist so should be perfectly safe).
  41. The --docker-image-hash option can be used to specify the hash of a particular
  42. base image to use. These hashes can be found under the "RepoDigests" field of
  43. "docker image inspect <image>". They will be reported in the form "sha256:<hash>";
  44. only need the <hash> part is needed
  45. EOF
  46. }
  47. if [ $# != 0 ] ; then
  48. while true ; do
  49. case "$1" in
  50. --help|-h)
  51. usage
  52. exit 0
  53. ;;
  54. --distro|-d)
  55. DISTRO="$2"
  56. shift 2
  57. ;;
  58. --suite|-s)
  59. SUITE="$2"
  60. shift 2
  61. ;;
  62. --arch|-a)
  63. ARCH="$2"
  64. shift 2
  65. ;;
  66. --lxc)
  67. LXC=1
  68. shift 1
  69. ;;
  70. --vbox)
  71. VBOX=1
  72. shift 1
  73. ;;
  74. --docker)
  75. DOCKER=1
  76. shift 1
  77. ;;
  78. --docker-image-digest)
  79. DOCKER_IMAGE_HASH="$2"
  80. shift 2
  81. ;;
  82. --*)
  83. echo "unrecognized option $1"
  84. exit 1
  85. ;;
  86. *)
  87. break
  88. ;;
  89. esac
  90. done
  91. fi
  92. if [ $DOCKER = "1" ]; then
  93. MIRROR_DEFAULT=172.17.0.1
  94. else
  95. MIRROR_DEFAULT=127.0.0.1
  96. fi
  97. MIRROR_BASE=http://${MIRROR_HOST:-$MIRROR_DEFAULT}:3142
  98. if [ $DISTRO = "ubuntu" ]; then
  99. MIRROR=$MIRROR_BASE/archive.ubuntu.com/ubuntu
  100. SECURITY_MIRROR=$MIRROR_BASE/security.ubuntu.com/ubuntu
  101. components=main,universe
  102. elif [ $DISTRO = "debian" ]; then
  103. MIRROR=$MIRROR_BASE/ftp.debian.org/debian
  104. SECURITY_MIRROR=$MIRROR_BASE/security.debian.org/
  105. components=main,contrib
  106. fi
  107. mkdir -p var
  108. if [ ! -e var/id_rsa ]; then
  109. ssh-keygen -t rsa -f var/id_rsa -N ""
  110. fi
  111. OUT=base-$SUITE-$ARCH
  112. FLAVOUR=virtual
  113. if [ $ARCH = "amd64" -a $SUITE = "hardy" ]; then
  114. FLAVOUR=server
  115. fi
  116. if [ $DISTRO = "debian" -a $ARCH = "amd64" ]; then
  117. FLAVOUR=amd64
  118. elif [ $DISTRO = "debian" -a $ARCH = "i386" -a \($SUITE = "squeeze" -o $SUITE = "lenny" -o $SUITE = "etch" -o $SUITE = "sarge" -o $SUITE = "woody" -o $SUITE = "potato" -o $SUITE = "slink" -o $SUITE = "hamm" -o $SUITE = "bo" -o $SUITE = "rex" -o $SUITE = "buzz"\) ]; then
  119. FLAVOUR=686
  120. elif [ $DISTRO = "debian" ]; then
  121. FLAVOUR=686-pae
  122. fi
  123. LOCALE_PKG=language-pack-en
  124. if [ $DISTRO = "debian" ]; then
  125. LOCALE_PKG=locales
  126. fi
  127. addpkg=pciutils,build-essential,git,subversion,$LOCALE_PKG,wget,lsb-release
  128. if [ $DISTRO = "ubuntu" ]; then
  129. # Need comma at end to work around an issue with apt for Debian <= Wheezy regarding empty strings
  130. #
  131. # If we left the comma down below when adding KERNEL_PKG to addpkg, the fact that KERNEL_PKG is undefined
  132. # if DISTRO is debian would result in two commas in a row (,,), which is interpreted by apt-get as the
  133. # package with the name empty string (""). This triggers a bug with apt versions < 1.0.3. So by adding the
  134. # comma to the end of KERNEL_PKG, we are including that comma if the distro is ubuntu (and therefore we do
  135. # have a kernel package that needs to be installed). If KERNEL_PKG is not set (i.e. we have Debian as the
  136. # distro), then we don't add that extra comma and therefore, we don't end up with two commas in a row.
  137. #
  138. # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=744940
  139. # http://anonscm.debian.org/cgit/apt/apt.git/commit/?h=1.0.3&id=d99854cac4065bc7b337815fb2116269d58dab73
  140. KERNEL_PKG=linux-image-generic,
  141. fi
  142. GRUB_PKG=grub
  143. if [ $DISTRO = "ubuntu" ]; then
  144. GRUB_PKG=grub-pc
  145. fi
  146. if [ $LXC = "1" ]; then
  147. addpkg=$addpkg,lxc
  148. if [ $DISTRO = "debian" ]; then
  149. addpkg=$addpkg,sudo
  150. fi
  151. else
  152. # Lack of comma after KERNEL_PKG is not a typo
  153. addpkg=$addpkg,${KERNEL_PKG}${GRUB_PKG},openssh-server
  154. fi
  155. # Remove cron to work around vmbuilder issue when umounting /dev on target
  156. removepkg=cron
  157. if [ $DOCKER = "1" ]; then
  158. addpkg=`echo $addpkg | tr ',' ' '`
  159. mkdir -p docker
  160. cd docker
  161. if [ -n "$DOCKER_IMAGE_HASH" ]; then
  162. base_image="$DISTRO@sha256:$DOCKER_IMAGE_HASH"
  163. OUT=base-$DOCKER_IMAGE_HASH-$ARCH
  164. else
  165. base_image="$DISTRO:$SUITE"
  166. fi
  167. # Generate the dockerfile
  168. cat << EOF > $OUT.Dockerfile
  169. FROM $base_image
  170. ENV DEBIAN_FRONTEND=noninteractive
  171. RUN echo 'Acquire::http { Proxy "$MIRROR_BASE"; };' > /etc/apt/apt.conf.d/50cacher
  172. RUN apt-get update && apt-get --no-install-recommends -y install $addpkg
  173. RUN useradd -ms /bin/bash -U $DISTRO
  174. USER $DISTRO:$DISTRO
  175. WORKDIR /home/$DISTRO
  176. CMD ["sleep", "infinity"]
  177. EOF
  178. docker build --pull -f $OUT.Dockerfile -t $OUT .
  179. exit 0
  180. fi
  181. if [ $VBOX = "1" ]; then
  182. NAME="$SUITE-$ARCH"
  183. if ! vagrant status | grep "$NAME" | grep "not created" > /dev/null; then
  184. echo "Vagrant machine "$NAME" already exists, please remove it first (vagrant destroy "$NAME")"
  185. exit 1
  186. fi
  187. DISTRO_USER_CREATE=0
  188. if [ $DISTRO = "debian" ]; then
  189. # we use a vagrant provider
  190. DISTRO_USER_CREATE=1
  191. fi
  192. vagrant up "$NAME"
  193. if [ $DISTRO_USER_CREATE = "1" ]; then
  194. vagrant ssh "$NAME" -c "sudo useradd -m -s /bin/bash $DISTRO"
  195. fi
  196. vagrant ssh "$NAME" -c "sudo mkdir -p /root/.ssh && sudo chmod 700 /root/.ssh"
  197. vagrant ssh "$NAME" -c "sudo sh -c 'cat >> /root/.ssh/authorized_keys'" < var/id_rsa.pub
  198. vagrant ssh "$NAME" -c "sudo -u $DISTRO mkdir -p /home/$DISTRO/.ssh && sudo -u $DISTRO chmod 700 /home/$DISTRO/.ssh"
  199. vagrant ssh "$NAME" -c "sudo sh -c 'cat >> /home/$DISTRO/.ssh/authorized_keys'" < var/id_rsa.pub
  200. VBoxManage snapshot "Gitian-$NAME" take "Gitian-Clean"
  201. vagrant suspend "$NAME"
  202. exit 0
  203. fi
  204. if [ $LXC = "1" ]; then
  205. if [ -e $OUT ]; then
  206. echo $OUT already exists, please remove it first
  207. exit 1
  208. fi
  209. sudo rm -rf $OUT-bootstrap
  210. # Need universe for lxc in lucid
  211. unset preserve_env
  212. if [ "$GITIAN_SUDO_USE_DEBOOTSTRAP_DIR" = "yes" ]; then
  213. echo "sudo will preserve (some) env flags"
  214. preserve_env=yes # if you would want to set false then unset this variable
  215. fi
  216. env -i LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 DEBOOTSTRAP_DIR="$DEBOOTSTRAP_DIR" sudo ${preserve_env+--preserve-env} debootstrap --arch=$ARCH --include=$addpkg --exclude=$removepkg --components=$components $SUITE $OUT-bootstrap $MIRROR
  217. # Fix lxc issue
  218. if [ -f $OUT-bootstrap/usr/lib/lxc/lxc-init ]
  219. then
  220. sudo cp $OUT-bootstrap/usr/lib/lxc/lxc-init $OUT-bootstrap/usr/sbin/init.lxc
  221. else
  222. if [ $ARCH = "amd64" ]
  223. then
  224. if [ -f $OUT-bootstrap/usr/lib/x86_64-linux-gnu/lxc/lxc-init ]
  225. then
  226. sudo cp $OUT-bootstrap/usr/lib/x86_64-linux-gnu/lxc/lxc-init $OUT-bootstrap/usr/sbin/init.lxc
  227. fi
  228. else
  229. if [ -f $OUT-bootstrap/usr/lib/i386-linux-gnu/lxc/lxc-init ]
  230. then
  231. sudo cp $OUT-bootstrap/usr/lib/i386-linux-gnu/lxc/lxc-init $OUT-bootstrap/usr/sbin/init.lxc
  232. fi
  233. fi
  234. fi
  235. dd if=/dev/zero of=$OUT-lxc bs=1M count=1 seek=12287
  236. /sbin/mkfs.ext4 -F $OUT-lxc
  237. t=`mktemp -d gitian.XXXXXXXX`
  238. sudo mount $OUT-lxc $t
  239. sudo cp -a $OUT-bootstrap/* $t
  240. sudo umount $t
  241. rmdir $t
  242. sudo rm -rf $OUT-bootstrap
  243. mv $OUT-lxc $OUT
  244. # bootstrap-fixup is done in libexec/make-clean-vm
  245. else
  246. if [ -e $OUT.qcow2 ]; then
  247. echo $OUT.qcow2 already exists, please remove it first
  248. exit 1
  249. fi
  250. libexec/config-bootstrap-fixup
  251. rm -rf $OUT
  252. env -i LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 sudo vmbuilder kvm $DISTRO --rootsize 10240 --arch=$ARCH --suite=$SUITE --addpkg=$addpkg --removepkg=$removepkg --ssh-key=var/id_rsa.pub --ssh-user-key=var/id_rsa.pub --mirror=$MIRROR --security-mirror=$SECURITY_MIRROR --dest=$OUT --flavour=$FLAVOUR --firstboot=`pwd`/target-bin/bootstrap-fixup
  253. mv $OUT/*.qcow2 $OUT.qcow2
  254. rm -rf $OUT
  255. # bootstrap-fixup is done on first boot
  256. fi