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.
 
 
 

130 lines
3.5 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. kill_container() {
  16. # Kill any running container
  17. if systemctl --quiet is-active $UNIT ; then
  18. echo "Stopping container..."
  19. # We could use "machinectl terminate", but that will wait
  20. # for a clean shutdown or timeout; we don't need a clean
  21. # shutdown, so send a SIGTERM twice to get systemd-nspawn
  22. # to terminate pretty quickly
  23. systemctl kill $UNIT
  24. sleep 2
  25. systemctl kill $UNIT
  26. # Then wait for it to really stop
  27. systemctl stop $UNIT
  28. fi
  29. # If systemd-nspawn returned with a failure code,
  30. # the transient service unit file will stick around,
  31. # so make sure we clear that.
  32. if systemctl --quiet is-failed $UNIT ; then
  33. systemctl reset-failed $UNIT
  34. fi
  35. }
  36. start_container() {
  37. # Start the container
  38. kill_container
  39. echo "Starting container..."
  40. systemd-run --unit=$UNIT systemd-nspawn \
  41. --quiet \
  42. --keep-unit \
  43. --boot \
  44. --directory $(realpath $FS) \
  45. --machine $MACH
  46. echo "Waiting..."
  47. while ! env SYSTEMD_LOG_LEVEL=0 machinectl shell $MACH /bin/true ; do
  48. sleep 0.1
  49. done
  50. }
  51. FAILED=0
  52. run() {
  53. # Run a command inside the container
  54. echo "+" "$1"
  55. # machinectl doesn't propagate return codes, so append something
  56. # to the command that saves the result of what we ran.
  57. echo "99" > $FS/jim-cmd-result
  58. CMD="$1 ; echo \$? > /jim-cmd-result"
  59. # Run it
  60. env SYSTEMD_LOG_LEVEL=notice machinectl \
  61. shell $MACH /usr/bin/env IN_CHROOT=1 \
  62. bash -c "$CMD"
  63. # Check result
  64. RET=$(cat $FS/jim-cmd-result)
  65. rm -f $FS/jim-cmd-result
  66. if [ $RET -ne 0 ] && [ "$1" != "exec bash" ] ; then
  67. printf "%s\n" "----------- WARNING: failed with exit code $RET"
  68. FAILED=$RET
  69. sleep 5
  70. fi
  71. }
  72. set -e
  73. start_container
  74. run "resolvconf --disable-updates"
  75. run "echo 'nameserver 8.8.8.8' > /run/resolvconf/resolv.conf"
  76. #run "dbus-uuidgen > /var/lib/dbus/machine-id"
  77. #run "dpkg-divert --local --rename --add /sbin/initctl"
  78. #run "ln -sf /bin/true /sbin/initctl"
  79. #run "dpkg-divert --local --rename --add /usr/sbin/update-grub"
  80. #run "ln -sf /bin/true /usr/sbin/update-grub"
  81. set +e
  82. if [ -z "$1" ] ; then
  83. run "exec bash"
  84. else
  85. run "$1"
  86. fi
  87. echo "Cleaning up..."
  88. # Manually clean up some unnecessary things that show up after booting
  89. # an image and installing packages. This doesn't get everything, but
  90. # what's left should be fine.
  91. run "apt-get clean"
  92. run "rm -f /core /boot/grub/grubenv"
  93. run "rm -f /var/lib/systemd/random-seed"
  94. run "rm -f /var/lib/ubuntu-drivers-common/last_gfx_boot"
  95. run "rm -f /var/lib/NetworkManager/*"
  96. run "rm -f /root/.bash_history"
  97. #run "rm /sbin/initctl"
  98. #run "dpkg-divert --rename --remove /sbin/initctl"
  99. #run "rm /usr/sbin/update-grub"
  100. #run "dpkg-divert --rename --remove /usr/sbin/update-grub"
  101. #run "rm /var/lib/dbus/machine-id"
  102. #run "> /etc/resolv.conf"
  103. kill_container
  104. echo "Done"
  105. if [ $FAILED -ne 0 ] ; then
  106. exit $FAILED
  107. fi
  108. exit 0