#!/usr/bin/env python3
# Copyright (c) 2006-2023 Arastra, Inc.  All rights reserved.
# Arastra, Inc. Confidential and Proprietary.

'''
Eos initialization script, installed as /usr/bin/EosInit. It is
executed by /etc/rc.d/init.d/Eos early in the system bootup process.
'''
import errno
import optparse # pylint: disable=deprecated-module
import sys
import Ark
import EosInit
import SwagBoot
import Tac
from VeosHypervisor import runningInDocker

def EosStart():
   platform = Ark.getPlatform()
   if platform not in [ "ceoslab", "ceossai", "ceosdsf" ] and not \
      ( platform == "veos" and runningInDocker() ):
      # Load modules required by Eos packages.
      Tac.run( [ "/sbin/modprobe", "tun" ], input="" )
      Tac.run( [ "/sbin/modprobe", "8021q" ], input="" )
      Tac.run( [ "/sbin/modprobe", "rbfd" ], input="" )
      Tac.run( [ "/sbin/modprobe", "nf_defrag_ipv6" ], input="" )
      with open( '/proc/modules', 'r' ) as file:
         if "scd" not in file.read():
            Tac.run( [ "/sbin/modprobe", "kshim" ], input="" )

   if platform == "veos" and not runningInDocker():
      # On veos platforms, we would like to start acpid service
      # to process to listen to virsh shutdown command and gracefully
      # shutdown the vm.
      try:
         Tac.run( [ "/sbin/modprobe", "button" ], input="" )
         Tac.run( [ "systemctl", "restart", "acpid" ], stdout=Tac.CAPTURE )
      except Tac.SystemCommandError as e:
         print( f"veos: {e.output}" )

   # Create a symlink Cli and FastCli since Cli has been deprecated
   Tac.run( [ "ln", "-s", "-f", "/usr/bin/FastCli",
              "/usr/bin/Cli" ], stdout=Tac.CAPTURE )

   # Start agents and reload ProcMgr given our cellType and swagRole.
   EosInit.startStage2Agents()

   # BUG833368: Disable THP by default, apps needing it can enable it
   # Disable THP so khugepaged won't run, apps that need THP can enable it
   # In case the file doesn't exist (e.g. ceoslab), just ignore the error and move on
   try:
      with open( "/sys/kernel/mm/transparent_hugepage/enabled", 'w' ) as file:
         file.write( "never" )
   except OSError as e:
      if e.errno in ( errno.ENOENT, errno.EROFS ):
         # Some platforms don't have this file, and sometimes this file is read-only
         # in cEOS-lab environments (where kernel parameters apply to the host).
         pass

def stage1Init():
   print( "Starting stage 1 EOS initialization" )
   EosInit.restoreASUBootImage()
   SwagBoot.stage1Init()

def stage2Init():
   print( "Starting stage 2 EOS initialization" )
   EosStart()

if __name__ == "__main__":
   op = optparse.OptionParser( usage = "%prog [options]" )
   op.add_option( "--stage", help="initialization stage to run",
                  action="store", choices=["1", "2"] )
   opts, args = op.parse_args()
   if args:
      op.error( "Unexpected arguments" )
   if not opts.stage:
      op.error( "You must specify the initialization stage to run" )
   stage = int( opts.stage )
   with open('/var/log/EosInitStage' + str(stage), 'a') as logfile :
      sys.stdout = logfile
      if stage == 1:
         stage1Init()
      elif stage == 2:
         stage2Init()
