/* * Copyright (c) 2019 Huawei Technologies Co., Ltd. * A-Tune is licensed under the Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * http://license.coscl.org.cn/MulanPSL2 * 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 v2 for more details. * Create: 2019-10-29 */ package config import ( "fmt" "gitee.com/openeuler/A-Tune/common/log" "gitee.com/openeuler/A-Tune/common/utils" "net" "path" "strings" "github.com/go-ini/ini" ) var Version = "no version specified" // application common config const ( EnvAddr = "ATUNED_ADDR" EnvPort = "ATUNED_PORT" EnvTLS = "ATUNED_TLS" EnvCaCert = "ATUNED_CACERT" EnvClientCert = "ATUNED_CLIENTCERT" EnvClientKey = "ATUNED_CLIENTKEY" EnvServerCN = "ATUNED_SERVERCN" DefaultProtocol = "unix" DefaultTgtAddr = "/var/run/atuned/atuned.sock" DefaultTgtPort = "" ) // default path config const ( DefaultPath = "/usr/lib/atuned/" DefaultModDaemonSvrPath = DefaultPath + "modules" DefaultProfilePath = DefaultPath + "profiles" DefaultConfPath = "/etc/atuned/" DefaultTuningPath = DefaultConfPath + "tuning/" DefaultRulePath = DefaultConfPath + "rules/" DefaultAnalysisPath = "/usr/libexec/atuned/analysis" DefaultTempPath = "/run/atuned" DefaultCheckerPath = "/usr/share/atuned/checker/" DefaultBackupPath = "/usr/share/atuned/backup/" DefaultTuningLogPath = "/var/atuned" ) // log config const ( Formatter = "text" Modes = "console" ) // python service url const ( Protocol string = "http" APIVersion string = "v1" ConfiguratorURI string = "setting" MonitorURI string = "monitor" OptimizerURI string = "optimizer" CollectorURI string = "collector" ClassificationURI string = "classification" ProfileURI string = "profile" TrainingURI string = "training" TransferURI string = "transfer" DetectingURI string = "detecting" ) // database config const ( DatabasePath string = "/var/lib/atuned" DatabaseType string = "sqlite3" DatabaseName string = "atuned.db" ) // monitor config const ( FileFormat string = "xml" ) // tuning config const ( TuningFile string = "tuning.log" TuningRuleFile string = "tuning_rules.grl" TuningRestoreConfig string = "-tuning-restore.conf" DefaultTimeFormat string = "2006-01-02 15:04:05.000" Percent float64 = 0.6 ) // client yaml config var ( EvaluationType = []string{"negative", "positive"} ) // the grpc server config var ( TransProtocol string Address string Connect string Port string LocalHost string RestPort string EngineHost string EnginePort string GrpcTLS bool RestTLS bool EngineTLS bool TLSServerCaFile string TLSServerCertFile string TLSServerKeyFile string TLSRestServerCertFile string TLSRestServerKeyFile string TLSRestCACertFile string TLSEngineClientCertFile string TLSEngineClientKeyFile string TLSEngineServerCertFile string TLSEngineServerKeyFile string TLSEngineCACertFile string ) // the tuning configs var ( Noise float64 SelFeature bool ) // the system config in atuned.cnf var ( Disk string Network string ) // Cfg type, the type that load the conf file type Cfg struct { Raw *ini.File } //Load method load the default conf file func (c *Cfg) Load() error { defaultConfigFile := path.Join(DefaultConfPath, "atuned.cnf") exist, err := utils.PathExist(defaultConfigFile) if err != nil { return err } if !exist { return fmt.Errorf("could not find default config file") } cfg, err := ini.Load(defaultConfigFile) if err != nil { return fmt.Errorf("failed to parse %s, %v", defaultConfigFile, err) } c.Raw = cfg section := cfg.Section("server") TransProtocol = section.Key("protocol").MustString(DefaultProtocol) Address = section.Key("address").MustString(DefaultTgtAddr) if section.HasKey("connect") { Connect = section.Key("connect").MustString("") } if section.HasKey("port") { Port = section.Key("port").MustString(DefaultTgtPort) } LocalHost = section.Key("rest_host").MustString("localhost") RestPort = section.Key("rest_port").MustString("8383") EngineHost = section.Key("engine_host").MustString("localhost") EnginePort = section.Key("engine_port").MustString("3838") utils.RestHost = LocalHost utils.RestPort = RestPort if section.HasKey("grpc_tls") { GrpcTLS = section.Key("grpc_tls").MustBool(false) } if section.HasKey("rest_tls") { RestTLS = section.Key("rest_tls").MustBool(true) } if section.HasKey("engine_tls") { EngineTLS = section.Key("engine_tls").MustBool(true) } if GrpcTLS { TLSServerCaFile = section.Key("tlsservercafile").MustString("") TLSServerCertFile = section.Key("tlsservercertfile").MustString("") TLSServerKeyFile = section.Key("tlsserverkeyfile").MustString("") } if RestTLS { TLSRestServerCertFile = section.Key("tlsrestservercertfile").MustString("") TLSRestServerKeyFile = section.Key("tlsrestserverkeyfile").MustString("") TLSRestCACertFile = section.Key("tlsrestcacertfile").MustString("") } if EngineTLS { TLSEngineClientCertFile = section.Key("tlsengineclientcertfile").MustString("") TLSEngineClientKeyFile = section.Key("tlsengineclientkeyfile").MustString("") TLSEngineServerCertFile = section.Key("tlsengineservercertfile").MustString("") TLSEngineServerKeyFile = section.Key("tlsengineserverkeyfile").MustString("") TLSEngineCACertFile = section.Key("tlsenginecacertfile").MustString("") } section = cfg.Section("system") Disk = section.Key("disk").MustString("") Network = section.Key("network").MustString("") validNetwork, err := getValidNetwork(Network) if err != nil { return err } if Network != validNetwork { section.Key("network").SetValue(validNetwork) if err := cfg.SaveTo(defaultConfigFile); err != nil { return err } Network = validNetwork } section = cfg.Section("tuning") Noise = section.Key("noise").MustFloat64(0.000000001) SelFeature = section.Key("sel_feature").MustBool(false) if err := initLogging(cfg); err != nil { return err } return nil } //NewCfg method create the cfg struct that store the conf file func NewCfg() *Cfg { return &Cfg{ Raw: ini.Empty(), } } func initLogging(cfg *ini.File) error { modes := strings.Split(Modes, ",") err := log.InitLogger(modes, cfg) return err } // GetURL return the url func GetURL(uri string) string { protocol := Protocol if IsEnginePort(uri) { if EngineTLS { protocol = "https" } return fmt.Sprintf("%s://%s:%s/%s/%s", protocol, EngineHost, EnginePort, APIVersion, uri) } if RestTLS { protocol = "https" } url := fmt.Sprintf("%s://%s:%s/%s/%s", protocol, LocalHost, RestPort, APIVersion, uri) return url } // IsEnginePort return true if using opt port and host func IsEnginePort(uri string) bool { if strings.EqualFold(uri, OptimizerURI) { return true } if strings.EqualFold(uri, ClassificationURI) { return true } if strings.EqualFold(uri, TransferURI) { return true } if strings.EqualFold(uri, TrainingURI) { return true } if strings.EqualFold(uri, DetectingURI) { return true } return false } func getValidNetwork(network string) (string, error) { interfaces, err := net.Interfaces() if err != nil { return "", err } validNetwork := make([]string, 0) for i := 0; i < len(interfaces); i++ { if interfaces[i].Flags&net.FlagUp != 0 { address, err := interfaces[i].Addrs() if err != nil { return "", err } for _, addr := range address { if ip, ok := addr.(*net.IPNet); ok && !ip.IP.IsLoopback() && ip.IP.To4() != nil { if network == interfaces[i].Name { log.Infof("valid network : %s", network) return network, nil } validNetwork = append(validNetwork, interfaces[i].Name) } } } } if len(validNetwork) == 1 { log.Infof("valid network : %s", validNetwork[0]) return validNetwork[0], nil } return "", fmt.Errorf("please provide the valid network config in atuned.cnf") }