/* * Copyright (c) 2019 Huawei Technologies Co., Ltd. * A-Tune is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: * http://license.coscl.org.cn/MulanPSL * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v1 for more details. * Create: 2019-10-29 */ package main import ( "atune/common/config" "atune/common/log" "atune/common/registry" SVC "atune/common/service" "atune/common/sqlstore" "atune/common/utils" "fmt" "io/ioutil" "net" "os" "os/exec" "os/signal" "syscall" "github.com/coreos/go-systemd/daemon" "github.com/urfave/cli" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) const ( atunedUsage = `atuned daemon is the AI system daemon To get more info of how to use atuned: # atuned help ` ) type swServer struct { server *grpc.Server svcs map[string]interface{} } func newServer(rpc *grpc.Server) (*swServer, error) { server := new(swServer) server.server = rpc server.svcs = make(map[string]interface{}) return server, nil } func createSvcInsts(ctx *cli.Context, svr *swServer) error { if err := SVC.WalkServices(func(nm string, svc *SVC.ProfileService) error { inst, err := svc.NewInst(ctx) if err != nil { fmt.Printf("Create %s instance failed\n", nm) return nil } log.Infof("Create %s service successfully\n", nm) sinst, ok := inst.(SVC.SvrService) if !ok { return fmt.Errorf("not impletment SvrService") } if err := sinst.RegisterServer(svr.server); err != nil { return err } svr.svcs[nm] = inst return nil }); err != nil { return err } return nil } func loadModules(ctx *cli.Context, svr *swServer, path string) error { exist, err := utils.PathExist(path) if err != nil { return err } if !exist { return nil } if err := utils.LoadPlugins(path); err != nil { return err } if err := createSvcInsts(ctx, svr); err != nil { return err } return nil } func checkValid(ctx *cli.Context) error { return nil } func doBeforeJob(ctx *cli.Context) error { if err := checkValid(ctx); err != nil { return err } // Load conf file cfg := config.NewCfg() if err := cfg.Load(); err != nil { log.Errorf("Faild to load config file, error: %v", err) return fmt.Errorf("Faild to load config file, error: %v", err) } store := &sqlstore.Sqlstore{ Cfg: cfg, } // init the sqlite3 database engine if err := store.Init(); err != nil { log.Error(err) return err } services := registry.GetDaemonServices() for _, service := range services { log.Infof("initializing service: %s", service.Name) service.Instance.Set(cfg) if err := service.Instance.Init(); err != nil { return fmt.Errorf("service init faild: %v", err) } } // starting all service for _, srv := range services { service := srv backgroundService, ok := service.Instance.(registry.BackgroundService) if !ok { continue } go func() error { err := backgroundService.Run() if err != nil { log.Errorf("service %s running faild, reason: %v", service.Name, err) return err } return nil }() } return nil } func listenToSystemSignals(cmd *exec.Cmd) { signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, os.Interrupt, os.Kill, syscall.SIGKILL) select { case <-signalChan: syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) os.Exit(-1) } } func showlogo() { logo, err := ioutil.ReadFile("/usr/share/atuned/atune.logo") if err != nil { fmt.Print(err) } fmt.Print(string(logo)) } func runatuned(ctx *cli.Context) error { if err := checkValid(ctx); err != nil { return err } lis, err := net.Listen("tcp", config.Address+":"+config.Port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() server, err := newServer(s) if err != nil { return err } if err := loadModules(ctx, server, config.DefaultModDaemonSvrPath); err != nil { return err } /* Show atuned Log*/ showlogo() if err := utils.WaitForPyservice(); err != nil { log.Errorf("waiting for pyservice faild: %v", err) return err } log.Info("pyservice has been started") daemon.SdNotify(false, "READY=1") reflection.Register(s) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } return nil } func main() { app := cli.NewApp() app.Name = "atuned" app.Usage = atunedUsage app.Version = config.Version app.Before = doBeforeJob app.Action = runatuned if err := app.Run(os.Args); err != nil { fmt.Printf("%s\n", err) os.Exit(1) } }