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 3.9 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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-$NONPRIV_UID-$VERSION
  14. MACH=nilmbuntu-$NONPRIV_UID-$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. rsync -avP --delete files/ ${FS}/root/files/
  88. setup_networking
  89. start_container
  90. run "cat /etc/hosts.nilm >>/etc/hosts 2>/dev/null || true"
  91. run "hostnamectl --transient set-hostname nilmbuntu"
  92. set +e
  93. if [ -z "$1" ] ; then
  94. run "exec bash"
  95. else
  96. run "$1"
  97. fi
  98. echo "Cleaning up..."
  99. # Manually clean up some things that show up after booting an image
  100. # and installing packages. This doesn't get everything, but what's
  101. # left should be fine.
  102. run "apt clean"
  103. run "dpkg --clear-avail"
  104. run "> /etc/machine-id"
  105. run "rm -f /core /boot/grub/grubenv"
  106. run "rm -f /var/lib/systemd/random-seed"
  107. run "rm -f /var/lib/ubuntu-drivers-common/last_gfx_boot"
  108. run "rm -f /var/lib/NetworkManager/*"
  109. run "rm -f /root/.bash_history"
  110. run "rm -rf /root/files"
  111. kill_container
  112. echo "Done"
  113. if [ $FAILED -ne 0 ] ; then
  114. exit $FAILED
  115. fi
  116. exit 0