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.
 
 
 

151 lines
4.3 KiB

  1. #!/bin/bash
  2. # make sure this was run as root
  3. if [ $UID -ne 0 ] ; then
  4. echo "Need to be root; trying sudo"
  5. exec sudo env BUILD_CONFIG=$BUILD_CONFIG $0 "$@"
  6. fi
  7. . config || exit 0
  8. # Spawn a systemd container that boots the machine, then run the given
  9. # command. We can't execute systemd-nspawn directly, because that
  10. # only allows us to either boot the machine, or run a command (not
  11. # both). Instead let's execute systemd-nspawn in a transient systemd
  12. # unit, then enter it using machinectl.
  13. UNIT=nilmbuntu-run-$VERSION
  14. MACH=nilmbuntu-$VERSION
  15. setup_networking() {
  16. # We use a virtual ethernet adapter -- this requires that
  17. # systemd-networkd is installed and running on the host.
  18. if ! systemctl is-active systemd-networkd ; then
  19. echo "Starting systemd-networkd"
  20. systemctl start systemd-networkd
  21. fi
  22. # However, the current systemd-networkd from Debian is broken and
  23. # won't enable masquerading -- so do it manually
  24. IFACE=$(ip -4 route list default | head -1 | awk '{print $5}')
  25. echo 1 > /proc/sys/net/ipv4/ip_forward
  26. iptables -t nat -D POSTROUTING -o $IFACE -j MASQUERADE >/dev/null || true
  27. iptables -t nat -A POSTROUTING -o $IFACE -j MASQUERADE
  28. }
  29. kill_container() {
  30. # Kill any running container
  31. if systemctl --quiet is-active $UNIT ; then
  32. echo "Stopping container..."
  33. # We could use "machinectl terminate", but that will wait
  34. # for a clean shutdown or timeout; we don't need a clean
  35. # shutdown, so send a SIGTERM twice to get systemd-nspawn
  36. # to terminate pretty quickly
  37. systemctl kill $UNIT
  38. sleep 2
  39. systemctl kill $UNIT
  40. # Then wait for it to really stop
  41. systemctl stop $UNIT
  42. fi
  43. # If systemd-nspawn returned with a failure code,
  44. # the transient service unit file will stick around,
  45. # so make sure we clear that.
  46. if systemctl --quiet is-failed $UNIT ; then
  47. systemctl reset-failed $UNIT
  48. fi
  49. }
  50. start_container() {
  51. kill_container
  52. echo "Starting container..."
  53. systemd-run --unit=$UNIT systemd-nspawn \
  54. --quiet \
  55. --keep-unit \
  56. --boot \
  57. --network-veth \
  58. --directory $(realpath $FS) \
  59. --machine $MACH
  60. echo "Waiting..."
  61. while ! env SYSTEMD_LOG_LEVEL=0 machinectl shell $MACH /bin/true ; do
  62. sleep 0.1
  63. done
  64. }
  65. FAILED=0
  66. run() {
  67. # Run a command inside the container
  68. echo "+" "$1"
  69. # machinectl doesn't propagate return codes, so append something
  70. # to the command that saves the result of what we ran.
  71. echo "99" > $FS/jim-cmd-result
  72. CMD="$1 ; echo \$? > /jim-cmd-result"
  73. # Run it
  74. env SYSTEMD_LOG_LEVEL=notice machinectl \
  75. shell $MACH /usr/bin/env IN_CHROOT=1 \
  76. bash -c "$CMD"
  77. # Check result
  78. RET=$(cat $FS/jim-cmd-result)
  79. rm -f $FS/jim-cmd-result
  80. if [ $RET -ne 0 ] && [ "$1" != "exec bash" ] ; then
  81. printf "%s\n" "----------- WARNING: failed with exit code $RET"
  82. FAILED=$RET
  83. sleep 5
  84. fi
  85. }
  86. set -e
  87. setup_networking
  88. start_container
  89. run "resolvconf --disable-updates"
  90. run "echo 'nameserver 8.8.8.8' > /run/resolvconf/resolv.conf"
  91. run "echo '127.0.0.1 localhost' > /etc/hosts"
  92. run "cat /etc/hosts.nilm >>/etc/hosts 2>/dev/null || true"
  93. run "hostnamectl --transient set-hostname nilmbuntu"
  94. #run "dbus-uuidgen > /var/lib/dbus/machine-id"
  95. #run "dpkg-divert --local --rename --add /sbin/initctl"
  96. #run "ln -sf /bin/true /sbin/initctl"
  97. #run "dpkg-divert --local --rename --add /usr/sbin/update-grub"
  98. #run "ln -sf /bin/true /usr/sbin/update-grub"
  99. set +e
  100. if [ -z "$1" ] ; then
  101. run "exec bash"
  102. else
  103. run "$1"
  104. fi
  105. echo "Cleaning up..."
  106. # Manually clean up some things that show up after booting an image
  107. # and installing packages. This doesn't get everything, but what's
  108. # left should be fine.
  109. run "apt-get clean"
  110. run "> /etc/machine-id"
  111. run "rm -f /core /boot/grub/grubenv"
  112. run "rm -f /var/lib/systemd/random-seed"
  113. run "rm -f /var/lib/ubuntu-drivers-common/last_gfx_boot"
  114. run "rm -f /var/lib/NetworkManager/*"
  115. run "rm -f /root/.bash_history"
  116. #run "rm /sbin/initctl"
  117. #run "dpkg-divert --rename --remove /sbin/initctl"
  118. #run "rm /usr/sbin/update-grub"
  119. #run "dpkg-divert --rename --remove /usr/sbin/update-grub"
  120. #run "rm /var/lib/dbus/machine-id"
  121. #run "> /etc/resolv.conf"
  122. kill_container
  123. echo "Done"
  124. if [ $FAILED -ne 0 ] ; then
  125. exit $FAILED
  126. fi
  127. exit 0