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 8.9KB

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