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.

enter.sh 4.3 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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