Skip to content

Commit

Permalink
system: consolidate all configs under home/.config/ais
Browse files Browse the repository at this point in the history
* more precisely, "all configs" applies to all except aisnode (cluster)
* add home/.config constants to `cmn/fname`
* fix readmes, add references (scripts as well)
* separately, rm shutdown marker (not ready yet)
* plus, refactoring

Signed-off-by: Alex Aizman <[email protected]>
  • Loading branch information
alex-aizman committed Jul 7, 2022
1 parent 5ec9cf5 commit ecca6fe
Show file tree
Hide file tree
Showing 23 changed files with 132 additions and 149 deletions.
3 changes: 1 addition & 2 deletions ais/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,7 @@ func initDaemon(version, buildTime string) cos.Runner {
cos.ExitLogf(erfm, "local-config")
}

// Cleanup shutdown marker if exists.
deleteShutdownMarker()
// TODO: detect graceful shutdown, delete shutdown marker

config = &cmn.Config{}
err = cmn.LoadConfig(daemon.cli.globalConfigPath, daemon.cli.localConfigPath, daemon.cli.role, config)
Expand Down
3 changes: 1 addition & 2 deletions ais/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ func (p *proxy) recvCluMeta(cluMeta *cluMeta, action, caller string) (err error)
}

// stop proxy runner and return => rungroup.run
// TODO: write shutdown-marker
func (p *proxy) Stop(err error) {
var (
s string
Expand Down Expand Up @@ -2391,7 +2392,6 @@ func (p *proxy) httpdaeput(w http.ResponseWriter, r *http.Request) {
if !p.ensureIntraControl(w, r, true /* from primary */) {
return
}
writeShutdownMarker()
p.Stop(&errNoUnregister{msg.Action})
return
}
Expand Down Expand Up @@ -2468,7 +2468,6 @@ func (p *proxy) unreg(w http.ResponseWriter, r *http.Request, msg *apc.ActionMsg
}
cleanupConfigDir(p.Name(), keepInitialConfig)
}
writeShutdownMarker()
p.Stop(&errNoUnregister{msg.Action})
}

Expand Down
1 change: 1 addition & 0 deletions ais/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ func (t *target) initRecvHandlers() {
}

// stop gracefully
// TODO: write shutdown-marker
func (t *target) Stop(err error) {
// NOTE: vs metasync
t.regstate.Lock()
Expand Down
1 change: 0 additions & 1 deletion ais/tgtcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ func (t *target) unreg(action string, opts *apc.ActValRmNode) {
daemon.stopping.Store(true)
t.regstate.Unlock()

writeShutdownMarker()
if action == apc.ActShutdown {
debug.Assert(!opts.NoShutdown)
t.Stop(&errNoUnregister{action})
Expand Down
28 changes: 1 addition & 27 deletions ais/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ import (

"github.com/NVIDIA/aistore/3rdparty/glog"
"github.com/NVIDIA/aistore/api/apc"
"github.com/NVIDIA/aistore/api/env"
"github.com/NVIDIA/aistore/cluster"
"github.com/NVIDIA/aistore/cmn"
"github.com/NVIDIA/aistore/cmn/cos"
"github.com/NVIDIA/aistore/cmn/fname"
"github.com/NVIDIA/aistore/cmn/k8s"
)

Expand Down Expand Up @@ -225,7 +223,7 @@ func deploymentType() string {
return runtime.GOOS
}

// for AIS metadata filenames (constants), see cmn/fname*
// for AIS metadata filenames (constants), see `cmn/fname` package
func cleanupConfigDir(name string, keepInitialConfig bool) {
if !keepInitialConfig {
// remove plain-text (initial) config
Expand All @@ -242,27 +240,3 @@ func cleanupConfigDir(name string, keepInitialConfig bool) {
return nil
})
}

func writeShutdownMarker() {
markerDir := os.Getenv(env.AIS.ShutdownMarkerDir)
if markerDir == "" {
if k8s.Detect() == nil {
glog.Warningf("marker directory not specified, skipping writing shutdown marker")
}
return
}
f, err := cos.CreateFile(filepath.Join(markerDir, fname.ShutdownMarker))
if err != nil {
glog.Errorf("failed to create shutdown marker, %v", err)
}
if f != nil {
f.Close()
}
}

func deleteShutdownMarker() {
markerDir := os.Getenv(env.AIS.ShutdownMarkerDir)
if markerDir != "" {
cos.RemoveFile(filepath.Join(markerDir, fname.ShutdownMarker))
}
}
5 changes: 3 additions & 2 deletions api/authn/loadtoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ func LoadToken(tokenFile string) string {
tokenFile = os.Getenv(env.AuthN.TokenFile)
}
if tokenFile == "" {
// default config location
tokenFile = filepath.Join(jsp.DefaultAppConfigDir(), fname.Token)
// when generated via CLI (and without the `-f` option) - the location:
// $HOME/.config/ais/cli/<fname.Token>
tokenFile = filepath.Join(cos.HomeConfigDir(fname.HomeCLI), fname.Token)
mustLoad = false
}
_, err := jsp.LoadMeta(tokenFile, &token)
Expand Down
28 changes: 13 additions & 15 deletions api/env/ais.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,20 @@ package env

var (
AIS = struct {
Endpoint string
ShutdownMarkerDir string
IsPrimary string
PrimaryID string
SkipVerifyCrt string
UseHTTPS string
NumTarget string
NumProxy string
K8sPod string
Endpoint string
IsPrimary string
PrimaryID string
SkipVerifyCrt string
UseHTTPS string
NumTarget string
NumProxy string
K8sPod string
}{
Endpoint: "AIS_ENDPOINT",
IsPrimary: "AIS_IS_PRIMARY",
PrimaryID: "AIS_PRIMARY_ID",
SkipVerifyCrt: "AIS_SKIP_VERIFY_CRT",
UseHTTPS: "AIS_USE_HTTPS",
ShutdownMarkerDir: "AIS_SHUTDOWN_MARKER_DIR",
Endpoint: "AIS_ENDPOINT",
IsPrimary: "AIS_IS_PRIMARY",
PrimaryID: "AIS_PRIMARY_ID",
SkipVerifyCrt: "AIS_SKIP_VERIFY_CRT",
UseHTTPS: "AIS_USE_HTTPS",

// Env variables used for tests or CI
NumTarget: "NUM_TARGET",
Expand Down
3 changes: 2 additions & 1 deletion cmd/aisfs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/NVIDIA/aistore/api/env"
"github.com/NVIDIA/aistore/cmd/aisfs/fs"
"github.com/NVIDIA/aistore/cmn/cos"
"github.com/NVIDIA/aistore/cmn/fname"
"github.com/NVIDIA/aistore/cmn/jsp"
)

Expand Down Expand Up @@ -116,7 +117,7 @@ func (c *Config) writeTo(srvCfg *fs.ServerConfig) {
func loadConfig(bucket string) (cfg *Config, err error) {
var (
configFname = bucket + ".aisfs.mount.json"
configDir = jsp.DefaultAppConfigDir()
configDir = cos.HomeConfigDir(fname.HomeAisFS) // $HOME/.config/ais/aisfs
)
cfg = &Config{}
if err = jsp.LoadAppConfig(configDir, configFname, &cfg); err != nil {
Expand Down
64 changes: 32 additions & 32 deletions cmd/authn/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,6 @@ func init() {
flag.StringVar(&configPath, "config", "", svcName+" configuration")
}

// Set up glog with options from configuration file
func updateLogOptions() error {
if err := cos.CreateDir(Conf.Log.Dir); err != nil {
return fmt.Errorf("failed to create log dir %q, err: %v", Conf.Log.Dir, err)
}
glog.SetLogDir(Conf.Log.Dir)

if Conf.Log.Level != "" {
v := flag.Lookup("v").Value
if v == nil {
return fmt.Errorf("nil -v Value")
}
if err := v.Set(Conf.Log.Level); err != nil {
return fmt.Errorf("failed to set log level = %s, err: %v", Conf.Log.Level, err)
}
}
return nil
}

func installSignalHandler() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-c
os.Exit(0)
}()
}

func printVer() {
fmt.Printf("version %s (build %s)\n", cmn.VersionAuthN+"."+build, buildtime)
}

func main() {
var configDir string
if len(os.Args) == 2 && os.Args[1] == "version" {
Expand Down Expand Up @@ -121,3 +89,35 @@ func main() {
cos.ExitLogf("Server failed: %v", err)
}
}

// Set up glog with options from configuration file
func updateLogOptions() error {
if err := cos.CreateDir(Conf.Log.Dir); err != nil {
return fmt.Errorf("failed to create log dir %q, err: %v", Conf.Log.Dir, err)
}
glog.SetLogDir(Conf.Log.Dir)

if Conf.Log.Level != "" {
v := flag.Lookup("v").Value
if v == nil {
return fmt.Errorf("nil -v Value")
}
if err := v.Set(Conf.Log.Level); err != nil {
return fmt.Errorf("failed to set log level = %s, err: %v", Conf.Log.Level, err)
}
}
return nil
}

func installSignalHandler() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-c
os.Exit(0)
}()
}

func printVer() {
fmt.Printf("version %s (build %s)\n", cmn.VersionAuthN+"."+build, buildtime)
}
8 changes: 1 addition & 7 deletions cmd/cli/commands/auth_hdlr.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,6 @@ func loginUserHandler(c *cli.Context) (err error) {
}

tokenPath := parseStrFlag(c, tokenFileFlag)
userPathUsed := tokenPath != ""
if tokenPath == "" {
tokenPath = filepath.Join(config.ConfigDir, fname.Token)
}
Expand All @@ -334,12 +333,7 @@ func loginUserHandler(c *cli.Context) (err error) {
fmt.Fprintf(c.App.Writer, "Token:\n%s\n", token.Token)
return fmt.Errorf(tokenSaveFailFmt, err)
}

if userPathUsed {
fmt.Fprintf(c.App.Writer, "Token saved to %s\n", tokenPath)
} else {
fmt.Fprintf(c.App.Writer, "Token(%s):\n%s\n", tokenPath, token.Token)
}
fmt.Fprintf(c.App.Writer, "Token saved to %s\n", tokenPath)
return nil
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/cli/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ var (
)

func init() {
ConfigDir = jsp.DefaultAppConfigDir()
// $HOME/.config/ais/cli
ConfigDir = cos.HomeConfigDir(fname.HomeCLI)
proto := "http"
if value := os.Getenv(env.AIS.UseHTTPS); cos.IsParseBool(value) {
proto = "https"
Expand Down
14 changes: 14 additions & 0 deletions cmn/cos/homedir.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ package cos
import (
"os"
"os/user"
"path/filepath"

"github.com/NVIDIA/aistore/cmn/debug"
"github.com/NVIDIA/aistore/cmn/fname"
)

func HomeDir() (string, error) {
Expand All @@ -17,3 +21,13 @@ func HomeDir() (string, error) {
}
return currentUser.HomeDir, nil
}

func HomeConfigDir(subdir string) (configDir string) {
home, err := HomeDir()
if err != nil {
debug.AssertNoErr(err)
Errorf("%v", err)
}
// $HOME/.config/ais/<subdir>
return filepath.Join(home, fname.HomeConfigsDir, fname.HomeAIS, subdir)
}
19 changes: 12 additions & 7 deletions cmn/fname/fname.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
// Package fname contains filename constants
// Package fname contains filename constants and common system directories
/*
* Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved.
*/
package fname

// See also: env/* for common environment variables
// See also: api/env for common environment variables

const (
HomeConfigsDir = ".config" // join(cos.HomeDir(), HomeConfigsDir)
HomeAIS = ".ais" // join(cos.HomeDir(), HomeConfigsDir, HomeAisDir)
HomeCLI = "cli" // ditto
HomeAuthN = "authn"
HomeAisFS = "aisfs"
)

const (
// aisnode config
Expand All @@ -26,17 +34,14 @@ const (
// CLI config
CliConfig = "cli.json" // see jsp/app.go

// AuthN config and DB
// AuthN: config and DB
AuthNConfig = "authn.json"
AuthDB = "authn.db"

// Token
Token = "auth.token"

// Markers

ShutdownMarker = ".ais.shutdown"

// Markers: per mountpath
MarkersDir = ".ais.markers"
ResilverMarker = "resilver"
RebalanceMarker = "rebalance"
Expand Down
37 changes: 8 additions & 29 deletions cmn/jsp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,20 @@ import (
"path/filepath"

"github.com/NVIDIA/aistore/cmn/cos"
"github.com/NVIDIA/aistore/cmn/debug"
)

// NOTE:
// The default app config directory is: $HOME/.config/ais
// e.g.: $HOME/.config/ais/cli.json - CLI config
// $HOME/.config/ais/auth.token - authentication token
// $HOME/.config/ais/<bucket>.aisfs.mount.json - aisfs mount config
func DefaultAppConfigDir() (configDir string) {
uhome, err := cos.HomeDir()
if err != nil {
debug.AssertNoErr(err)
cos.Errorf("%v", err)
}
return filepath.Join(uhome, ".config/ais")
}

// LoadAppConfig loads app config.
func LoadAppConfig(configDir, configFileName string, v interface{}) (err error) {
// Check if config file exists.
configFilePath := filepath.Join(configDir, configFileName)
if err = cos.Stat(configFilePath); err != nil {
func LoadAppConfig(configDir, configFname string, v interface{}) (err error) {
path := filepath.Join(configDir, configFname)
if err = cos.Stat(path); err != nil {
return err
}

// Load config from file.
if _, err = Load(configFilePath, v, Options{Indent: true}); err != nil {
return fmt.Errorf("failed to load config file %q: %v", configFilePath, err)
if _, err = Load(path, v, Options{Indent: true}); err != nil {
err = fmt.Errorf("failed to load config file %q: %v", path, err)
}
return
}

// SaveAppConfig writes app config.
func SaveAppConfig(configDir, configFileName string, v interface{}) (err error) {
// Check if config dir exists; if not, create one with default config.
configFilePath := filepath.Join(configDir, configFileName)
return Save(configFilePath, v, Options{Indent: true}, nil /*sgl*/)
func SaveAppConfig(configDir, configFname string, v interface{}) error {
path := filepath.Join(configDir, configFname)
return Save(path, v, Options{Indent: true}, nil /*sgl*/)
}
2 changes: 1 addition & 1 deletion deploy/dev/local/clean.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ if [[ -n ${GOBIN} ]]; then
fi

rm -rf ~/.ais* # cluster config and metadata
rm -rf ~/.config/ais # CLI and AuthN config and token, respectively
rm -rf ~/.config/ais # CLI, AuthN (config and DB), AuthN tokens produced via CLI, aisfs
rm -rf /tmp/ais* # user data and cluster metadata
rm -f ${build_dest}/ais* # 'ais' (CLI), 'aisnode', 'aisfs', and 'aisloader' binaries
rm -f ${build_dest}/authn # AuthN executable
Loading

0 comments on commit ecca6fe

Please sign in to comment.