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.2KB

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