From 4803847e5ef0c2aa099e8ba28e5818c4fc8247c8 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Fri, 10 Dec 2021 13:13:35 -0800 Subject: [PATCH] Remove the rw folder from the image after installing in KVM (#8746) * Remove the rw folder from the image after installing in KVM When the image is installed from within KVM and then loaded, some files (such as timer stamp files) are created as part of that bootup that then get into the final image. This can cause some side effects, such as systemd thinking that some persistent timers need to run because the last trigger time got missed. Therefore, at the end of the check_install.py script, remove the rw folder so that it doesn't exist in the image, and that when this image is started up in a KVM setup for the first time, it starts with a truly clean slate. Without this change, the issue seen was that for fstrim.timer, a stamp file would be present in /var/lib/systemd/timers (and for other timers that are marked as persistent). This would then cause fstrim.service to get started immediately when starting a QEMU setup if the timer for that service missed a trigger, and not wait 10 minutes after bootup. In the case of fstrim.timer, that means if the image was started in QEMU after next Monday, since that timer is scheduled to be triggered weekly. Signed-off-by: Saikrishna Arcot * Split installation of SONiC and test bootup into two separate scripts Just removing the rw directory causes other issues, since the first boot tasks no longer run since that file isn't present. Also, just recreating that file doesn't completely help, because there are some files that are moved from the /host folder into the base filesystem layer, and so are no longer available. Instead, split the installation of SONiC and doing the test bootup into two separate scripts and two separate KVM instances. The first KVM instance is the one currently being run, while the second one has the `-snapshot` flag added in, which means any changes to the disk image don't take effect. Signed-off-by: Saikrishna Arcot --- check_install.py | 16 ++++--------- install_sonic.py | 49 ++++++++++++++++++++++++++++++++++++++ scripts/build_kvm_image.sh | 30 +++++++++++++++++++++++ 3 files changed, 83 insertions(+), 12 deletions(-) create mode 100755 install_sonic.py diff --git a/check_install.py b/check_install.py index ed0d8018afe7..ecd3a8ee9a3b 100755 --- a/check_install.py +++ b/check_install.py @@ -15,11 +15,6 @@ def main(): args = parser.parse_args() - KEY_UP = '\x1b[A' - KEY_DOWN = '\x1b[B' - KEY_RIGHT = '\x1b[C' - KEY_LEFT = '\x1b[D' - login_prompt = 'sonic login:' passwd_prompt = 'Password:' cmd_prompt = "{}@sonic:~\$ $".format(args.u) @@ -37,22 +32,19 @@ def main(): raise time.sleep(1) - # select ONIE embed + # select default SONiC Image p.expect(grub_selection) - p.sendline(KEY_DOWN) + p.sendline() - # install sonic image + # bootup sonic image while True: - i = p.expect([login_prompt, passwd_prompt, grub_selection, cmd_prompt]) + i = p.expect([login_prompt, passwd_prompt, cmd_prompt]) if i == 0: # send user name p.sendline(args.u) elif i == 1: # send password p.sendline(args.P) - elif i == 2: - # select onie install - p.sendline() else: break diff --git a/install_sonic.py b/install_sonic.py new file mode 100755 index 000000000000..01785393f4eb --- /dev/null +++ b/install_sonic.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +import argparse +import pexpect +import sys +import time + + +def main(): + + parser = argparse.ArgumentParser(description='test_login cmdline parser') + parser.add_argument('-p', type=int, default=9000, help='local port') + + args = parser.parse_args() + + #KEY_UP = '\x1b[A' + KEY_DOWN = '\x1b[B' + #KEY_RIGHT = '\x1b[C' + #KEY_LEFT = '\x1b[D' + + grub_selection = "The highlighted entry will be executed" + + i = 0 + while True: + try: + p = pexpect.spawn("telnet 127.0.0.1 {}".format(args.p), timeout=600, logfile=sys.stdout, encoding='utf-8') + break + except Exception as e: + print(str(e)) + i += 1 + if i == 10: + raise + time.sleep(1) + + # select ONIE embed + p.expect(grub_selection) + p.sendline(KEY_DOWN) + + # select ONIE install + p.expect(['ONIE: Install OS']) + p.expect([grub_selection]) + p.sendline() + + # wait for grub, and exit + p.expect([grub_selection]) + + +if __name__ == '__main__': + main() diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index 6be223ebb9da..cfaba6521ed6 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -71,6 +71,8 @@ kvm_log=$(mktemp) trap on_exit EXIT trap on_error ERR +echo "Installing SONiC" + /usr/bin/kvm -m $MEM \ -name "onie" \ -boot "order=cd,once=d" -cdrom "$ONIE_RECOVERY_ISO" \ @@ -94,6 +96,34 @@ sleep 2.0 echo "to kill kvm: sudo kill $kvm_pid" +./install_sonic.py + +kill $kvm_pid + +echo "Booting up SONiC" + +/usr/bin/kvm -m $MEM \ + -name "onie" \ + -device e1000,netdev=onienet \ + -netdev user,id=onienet,hostfwd=:0.0.0.0:3041-:22 \ + -vnc 0.0.0.0:0 \ + -vga std \ + -snapshot \ + -drive file=$DISK,media=disk,if=virtio,index=0 \ + -serial telnet:127.0.0.1:$KVM_PORT,server > $kvm_log 2>&1 & + +kvm_pid=$! + +sleep 2.0 + +[ -d "/proc/$kvm_pid" ] || { + echo "ERROR: kvm died." + cat $kvm_log + exit 1 +} + +echo "to kill kvm: sudo kill $kvm_pid" + ./check_install.py -u $SONIC_USERNAME -P $PASSWD -p $KVM_PORT kill $kvm_pid