func KubeArmor(clusterName, gRPCPort, logPath string, enableKubeArmorPolicy, enableKubeArmorHostPolicy bool) {
	dm := NewKubeArmorDaemon(clusterName, gRPCPort, logPath, enableKubeArmorPolicy, enableKubeArmorHostPolicy)
	if K8s.InitK8sClient() {
		kg.Print("Initialized Kubernetes client")
		dm.K8sEnabled = true
		go dm.WatchK8sNodes()
		kg.Print("Started to monitor node events")
		time.Sleep(time.Second * 1)
		for dm.Node.NodeIP == "" {
			kg.Print("The node information is not updated yet")
			time.Sleep(time.Second * 1)
		}
		dm.Node.EnableKubeArmorPolicy = enableKubeArmorPolicy
		dm.Node.EnableKubeArmorHostPolicy = enableKubeArmorHostPolicy
	} else {
		dm.Node.NodeName = kl.GetHostName()
		dm.Node.NodeIP = kl.GetExternalIPAddr()
		dm.Node.KernelVersion = kl.GetCommandOutputWithoutErr("uname", []string{"-r"})
		dm.Node.KernelVersion = strings.TrimSuffix(dm.Node.KernelVersion, "\n")
		dm.EnableKubeArmorPolicy = false
		dm.Node.EnableKubeArmorPolicy = false
		dm.Node.EnableKubeArmorHostPolicy = enableKubeArmorHostPolicy
		dm.Node.PolicyEnabled = tp.KubeArmorPolicyEnabled
		kg.Print("Detected no Kubernetes")
	}
	if !dm.InitLogger() {
		kg.Err("Failed to intialize KubeArmor Logger")
		dm.DestroyKubeArmorDaemon()
		return
	}
	dm.Logger.Print("Initialized KubeArmor Logger")
	go dm.ServeLogFeeds()
	dm.Logger.Print("Started to serve gRPC-based log feeds")
	if dm.EnableKubeArmorPolicy || dm.EnableKubeArmorHostPolicy {
		if !dm.InitSystemMonitor() {
			dm.Logger.Err("Failed to initialize KubeArmor Monitor")
			dm.DestroyKubeArmorDaemon()
			return
		}
		dm.Logger.Print("Initialized KubeArmor Monitor")
		go dm.MonitorSystemEvents()
		dm.Logger.Print("Started to monitor system events")
		if !dm.InitRuntimeEnforcer() {
			dm.Logger.Print("Disabled KubeArmor Enforcer since No LSM is enabled")
		} else {
			dm.Logger.Print("Initialized KubeArmor Enforcer")
			if dm.EnableKubeArmorPolicy && !dm.EnableKubeArmorHostPolicy {
				dm.Logger.Print("Started to protect containers")
			} else if !dm.EnableKubeArmorPolicy && dm.EnableKubeArmorHostPolicy {
				dm.Logger.Print("Started to protect a host")
			} else if dm.EnableKubeArmorPolicy && dm.EnableKubeArmorHostPolicy {
				dm.Logger.Print("Started to protect a host and containers")
			}
		}
	}
	if dm.K8sEnabled && dm.EnableKubeArmorPolicy {
		dm.Logger.Printf("Container Runtime: %s", dm.Node.ContainerRuntimeVersion)
		if strings.HasPrefix(dm.Node.ContainerRuntimeVersion, "docker") {
			sockFile := false
			for _, candidate := range []string{"/var/run/docker.sock"} {
				if _, err := os.Stat(candidate); err == nil {
					sockFile = true
					break
				}
			}
			if sockFile {
				dm.GetAlreadyDeployedDockerContainers()
				go dm.MonitorDockerEvents()
			} else {
				for _, candidate := range []string{"/var/run/containerd/containerd.sock"} {
					if _, err := os.Stat(candidate); err == nil {
						sockFile = true
						break
					}
				}
				if sockFile {
					go dm.MonitorContainerdEvents()
				} else {
					dm.Logger.Err("Failed to monitor containers (Docker socket file is not accessible)")
					dm.DestroyKubeArmorDaemon()
					return
				}
			}
		} else {  
			sockFile := false
			for _, candidate := range []string{"/var/run/containerd/containerd.sock", "/var/snap/microk8s/common/run/containerd.sock"} {
				if _, err := os.Stat(candidate); err == nil {
					sockFile = true
					break
				}
			}
			if sockFile {
				go dm.MonitorContainerdEvents()
			} else {
				dm.Logger.Err("Failed to monitor containers (Containerd socket file is not accessible)")
				dm.DestroyKubeArmorDaemon()
				return
			}
		}
	}
	time.Sleep(time.Second * 1)
	if dm.K8sEnabled && dm.EnableKubeArmorPolicy {
		go dm.WatchK8sPods()
		dm.Logger.Print("Started to monitor Pod events")
		go dm.WatchSecurityPolicies()
		dm.Logger.Print("Started to monitor security policies")
	}
	if dm.K8sEnabled && dm.EnableKubeArmorHostPolicy {
		go dm.WatchHostSecurityPolicies()
		dm.Logger.Print("Started to monitor host security policies")
	}
	dm.Logger.Print("Initialized KubeArmor")
	sigChan := GetOSSigChannel()
	<-sigChan
	dm.Logger.Print("Got a signal to terminate KubeArmor")
	close(StopChan)
	dm.DestroyKubeArmorDaemon()
}
========== //
== Main == //
========== //
KubeArmor Function
package core
import (
	"os"
	"os/signal"
	"strings"
	"sync"
	"syscall"
	"time"
	kl "github.com/kubearmor/KubeArmor/KubeArmor/common"
	kg "github.com/kubearmor/KubeArmor/KubeArmor/log"
	tp "github.com/kubearmor/KubeArmor/KubeArmor/types"
	efc "github.com/kubearmor/KubeArmor/KubeArmor/enforcer"
	fd "github.com/kubearmor/KubeArmor/KubeArmor/feeder"
	mon "github.com/kubearmor/KubeArmor/KubeArmor/monitor"
)
var StopChan chan struct{}
func init() {
	StopChan = make(chan struct{})
}
type KubeArmorDaemon struct {
	ClusterName string
	Node tp.Node
	gRPCPort  string
	LogPath   string
	LogFilter string
	EnableKubeArmorPolicy     bool
	EnableKubeArmorHostPolicy bool
	K8sEnabled bool
	K8sPods     []tp.K8sPod
	K8sPodsLock *sync.RWMutex
	Containers     map[string]tp.Container
	ContainersLock *sync.RWMutex
	EndPoints     []tp.EndPoint
	EndPointsLock *sync.RWMutex
	SecurityPolicies     []tp.SecurityPolicy
	SecurityPoliciesLock *sync.RWMutex
	HostSecurityPolicies     []tp.HostSecurityPolicy
	HostSecurityPoliciesLock *sync.RWMutex
	ActivePidMap     map[string]tp.PidMap
	ActiveHostPidMap map[string]tp.PidMap
	ActivePidMapLock *sync.RWMutex
	ActiveHostMap     map[uint32]tp.PidMap
	ActiveHostMapLock *sync.RWMutex
	Logger *fd.Feeder
	SystemMonitor *mon.SystemMonitor
	RuntimeEnforcer *efc.RuntimeEnforcer
	WgDaemon sync.WaitGroup
}
func NewKubeArmorDaemon(clusterName, gRPCPort, logPath string, enableKubeArmorPolicy, enableKubeArmorHostPolicy bool) *KubeArmorDaemon {
	dm := new(KubeArmorDaemon)
	if clusterName == "" {
		if val, ok := os.LookupEnv("CLUSTER_NAME"); ok {
			dm.ClusterName = val
		} else {
			dm.ClusterName = "Default"
		}
	} else {
		dm.ClusterName = clusterName
	}
	dm.Node = tp.Node{}
	dm.gRPCPort = gRPCPort
	dm.LogPath = logPath
	dm.EnableKubeArmorPolicy = enableKubeArmorPolicy
	dm.EnableKubeArmorHostPolicy = enableKubeArmorHostPolicy
	dm.K8sEnabled = false
	dm.K8sPods = []tp.K8sPod{}
	dm.K8sPodsLock = new(sync.RWMutex)
	dm.Containers = map[string]tp.Container{}
	dm.ContainersLock = new(sync.RWMutex)
	dm.EndPoints = []tp.EndPoint{}
	dm.EndPointsLock = new(sync.RWMutex)
	dm.SecurityPolicies = []tp.SecurityPolicy{}
	dm.SecurityPoliciesLock = new(sync.RWMutex)
	dm.HostSecurityPolicies = []tp.HostSecurityPolicy{}
	dm.HostSecurityPoliciesLock = new(sync.RWMutex)
	dm.ActivePidMap = map[string]tp.PidMap{}
	dm.ActiveHostPidMap = map[string]tp.PidMap{}
	dm.ActivePidMapLock = new(sync.RWMutex)
	dm.ActiveHostMap = map[uint32]tp.PidMap{}
	dm.ActiveHostMapLock = new(sync.RWMutex)
	dm.Logger = nil
	dm.SystemMonitor = nil
	dm.RuntimeEnforcer = nil
	dm.WgDaemon = sync.WaitGroup{}
	return dm
}
func (dm *KubeArmorDaemon) DestroyKubeArmorDaemon() {
	if dm.RuntimeEnforcer != nil {
		if dm.CloseRuntimeEnforcer() {
			dm.Logger.Print("Stopped KubeArmor Enforcer")
		}
	}
	if dm.SystemMonitor != nil {
		if dm.CloseSystemMonitor() {
			dm.Logger.Print("Stopped KubeArmor Monitor")
		}
	}
	if dm.Logger != nil {
		dm.Logger.Print("Terminated KubeArmor")
	} else {
		kg.Print("Terminated KubeArmor")
	}
	time.Sleep(time.Second * 1)
	if dm.Logger != nil {
		if dm.CloseLogger() {
			kg.Print("Stopped KubeArmor Logger")
		}
	}
	kg.Print("Waiting for routine terminations")
	dm.WgDaemon.Wait()
}
func (dm *KubeArmorDaemon) InitLogger() bool {
	dm.Logger = fd.NewFeeder(dm.ClusterName, &dm.Node, dm.gRPCPort, dm.LogPath)
	return dm.Logger != nil
}
func (dm *KubeArmorDaemon) ServeLogFeeds() {
	dm.WgDaemon.Add(1)
	defer dm.WgDaemon.Done()
	go dm.Logger.ServeLogFeeds()
}
func (dm *KubeArmorDaemon) CloseLogger() bool {
	if err := dm.Logger.DestroyFeeder(); err != nil {
		kg.Print("Failed to destroy KubeArmor Logger")
		return false
	}
	return true
}
func (dm *KubeArmorDaemon) InitSystemMonitor() bool {
	dm.SystemMonitor = mon.NewSystemMonitor(dm.Node, dm.Logger, &dm.Containers, &dm.ContainersLock,
		&dm.ActivePidMap, &dm.ActiveHostPidMap, &dm.ActivePidMapLock, &dm.ActiveHostMap, &dm.ActiveHostMapLock)
	if dm.SystemMonitor == nil {
		return false
	}
	if err := dm.SystemMonitor.InitBPF(); err != nil {
		kg.Err(err.Error())
		return false
	}
	return true
}
func (dm *KubeArmorDaemon) MonitorSystemEvents() {
	dm.WgDaemon.Add(1)
	defer dm.WgDaemon.Done()
	if dm.EnableKubeArmorPolicy {
		go dm.SystemMonitor.TraceSyscall()
		go dm.SystemMonitor.UpdateLogs()
	}
	if dm.EnableKubeArmorHostPolicy {
		go dm.SystemMonitor.TraceHostSyscall()
		go dm.SystemMonitor.UpdateHostLogs()
	}
	if dm.EnableKubeArmorPolicy || dm.EnableKubeArmorHostPolicy {
		go dm.SystemMonitor.CleanUpExitedHostPids()
	}
}
func (dm *KubeArmorDaemon) CloseSystemMonitor() bool {
	if err := dm.SystemMonitor.DestroySystemMonitor(); err != nil {
		dm.Logger.Err("Failed to destroy KubeArmor Monitor")
		return false
	}
	return true
}
func (dm *KubeArmorDaemon) InitRuntimeEnforcer() bool {
	dm.RuntimeEnforcer = efc.NewRuntimeEnforcer(dm.Node, dm.Logger)
	return dm.RuntimeEnforcer != nil
}
func (dm *KubeArmorDaemon) CloseRuntimeEnforcer() bool {
	if err := dm.RuntimeEnforcer.DestroyRuntimeEnforcer(); err != nil {
		dm.Logger.Err("Failed to destory KubeArmor Enforcer")
		return false
	}
	return true
}
func GetOSSigChannel() chan os.Signal {
	c := make(chan os.Signal, 1)
	signal.Notify(c,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT,
		os.Interrupt)
	return c
}