func NewCloudCoreCommand() *cobra.Command {
opts := options.NewCloudCoreOptions()
cmd := &cobra.Command{
Use: "cloudcore",
Long: `CloudCore is the core cloud part of KubeEdge, which contains three modules: cloudhub,
edgecontroller, and devicecontroller. Cloudhub is a web server responsible for watching changes at the cloud side,
caching and sending messages to EdgeHub. EdgeController is an extended kubernetes controller which manages
edge nodes and pods metadata so that the data can be targeted to a specific edge node. DeviceController is an extended
kubernetes controller which manages devices so that the device metadata/status date can be synced between edge and cloud.`,
Run: func(cmd *cobra.Command, args []string) {
verflag.PrintAndExitIfRequested()
flag.PrintFlags(cmd.Flags())
// To help debugging, immediately log version
klog.Infof("Version: %+v", version.Get())
registerModules()
// start all modules
core.Run()
},
}
fs := cmd.Flags()
namedFs := opts.Flags()
verflag.AddFlags(namedFs.FlagSet("global"))
globalflag.AddGlobalFlags(namedFs.FlagSet("global"), cmd.Name())
for _, f := range namedFs.FlagSets {
fs.AddFlagSet(f)
}
usageFmt := "Usage:\n %s\n"
cols, _, _ := term.TerminalSize(cmd.OutOrStdout())
cmd.SetUsageFunc(func(cmd *cobra.Command) error {
fmt.Fprintf(cmd.OutOrStderr(), usageFmt, cmd.UseLine())
cliflag.PrintSections(cmd.OutOrStderr(), namedFs, cols)
return nil
})
cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine())
cliflag.PrintSections(cmd.OutOrStdout(), namedFs, cols)
})
return cmd
}
// registerModules register all the modules started in cloudcore
func registerModules() {
cloudhub.Register()
edgecontroller.Register()
devicecontroller.Register()
}
// Register register module
func Register(m Module) {
if isModuleEnabled(m.Name()) {
modules[m.Name()] = m //将具体的模块结构体放入一个以模块名为key的map映射中
log.LOGGER.Info("module " + m.Name() + " registered")
} else {
disabledModules[m.Name()] = m
log.LOGGER.Info("module " + m.Name() +
" is not register, please check modules.yaml")
}
}
//Run starts the modules and in the end does module cleanup
func Run() {
//Address the module registration and start the core
StartModules()
// monitor system signal and shutdown gracefully
GracefulShutdown()
}
coreContext := context.GetContext(context.MsgCtxTypeChannel)
go module.Start(coreContext)
// StartModules starts modules that are registered
func StartModules() {
coreContext := context.GetContext(context.MsgCtxTypeChannel)
modules := GetModules()
for name, module := range modules {
//Init the module
coreContext.AddModule(name)
//Assemble typeChannels for send2Group
coreContext.AddModuleGroup(name, module.Group())
go module.Start(coreContext)
log.LOGGER.Info("starting module " + name)
}
}
// GracefulShutdown is if it gets the special signals it does modules cleanup
func GracefulShutdown() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGINT, syscall.SIGHUP, syscall.SIGTERM,
syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, syscall.SIGABRT)
select {
case s := <-c:
log.LOGGER.Info("got os signal " + s.String())
//Cleanup each modules
modules := GetModules()
for name, module := range modules {
log.LOGGER.Info("Cleanup module " + name)
module.Cleanup()
}
}
}