Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate config-dir bring in certs-dir for TLS configuration #7033

Merged
merged 1 commit into from Jan 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 41 additions & 29 deletions cmd/common-main.go
Expand Up @@ -78,6 +78,42 @@ func loadLoggers() {

}

func newConfigDirFromCtx(ctx *cli.Context, option string, getDefaultDir func() string) *ConfigDir {
var dir string

switch {
case ctx.IsSet(option):
dir = ctx.String(option)
case ctx.GlobalIsSet(option):
dir = ctx.GlobalString(option)
// cli package does not expose parent's option option. Below code is workaround.
if dir == "" || dir == getDefaultDir() {
if ctx.Parent().GlobalIsSet(option) {
dir = ctx.Parent().GlobalString(option)
}
}
default:
// Neither local nor global option is provided. In this case, try to use
// default directory.
dir = getDefaultDir()
if dir == "" {
logger.FatalIf(errInvalidArgument, "%s option must be provided", option)
}
}

if dir == "" {
logger.FatalIf(errors.New("empty directory"), "%s directory cannot be empty", option)
}

// Disallow relative paths, figure out absolute paths.
dirAbs, err := filepath.Abs(dir)
logger.FatalIf(err, "Unable to fetch absolute path for %s=%s", option, dir)

logger.FatalIf(mkdirAllIgnorePerm(dirAbs), "Unable to create directory specified %s=%s", option, dir)

return &ConfigDir{path: dirAbs}
}

func handleCommonCmdArgs(ctx *cli.Context) {

// Get "json" flag from command line argument and
Expand Down Expand Up @@ -105,36 +141,12 @@ func handleCommonCmdArgs(ctx *cli.Context) {
globalCLIContext.Addr = ctx.String("address")
}

var configDir string

switch {
case ctx.IsSet("config-dir"):
configDir = ctx.String("config-dir")
case ctx.GlobalIsSet("config-dir"):
configDir = ctx.GlobalString("config-dir")
// cli package does not expose parent's "config-dir" option. Below code is workaround.
if configDir == "" || configDir == getConfigDir() {
if ctx.Parent().GlobalIsSet("config-dir") {
configDir = ctx.Parent().GlobalString("config-dir")
}
}
default:
// Neither local nor global config-dir option is provided. In this case, try to use
// default config directory.
configDir = getConfigDir()
if configDir == "" {
logger.FatalIf(errors.New("missing option"), "config-dir option must be provided")
}
}

if configDir == "" {
logger.FatalIf(errors.New("empty directory"), "Configuration directory cannot be empty")
}
// Set all config, certs and CAs directories.
globalConfigDir = newConfigDirFromCtx(ctx, "config-dir", defaultConfigDir.Get)
globalCertsDir = newConfigDirFromCtx(ctx, "certs-dir", defaultCertsDir.Get)
globalCertsCADir = &ConfigDir{path: filepath.Join(globalCertsDir.Get(), certsCADir)}

// Disallow relative paths, figure out absolute paths.
configDirAbs, err := filepath.Abs(configDir)
logger.FatalIf(err, "Unable to fetch absolute path for config directory %s", configDir)
setConfigDir(configDirAbs)
logger.FatalIf(mkdirAllIgnorePerm(globalCertsCADir.Get()), "Unable to create certs CA directory at %s", globalCertsCADir.Get())
}

// Parses the given compression exclude list `extensions` or `content-types`.
Expand Down
107 changes: 37 additions & 70 deletions cmd/config-dir.go
Expand Up @@ -19,7 +19,6 @@ package cmd
import (
"os"
"path/filepath"
"sync"

homedir "github.com/mitchellh/go-homedir"
)
Expand All @@ -41,63 +40,9 @@ const (
privateKeyFile = "private.key"
)

// ConfigDir - configuration directory with locking.
// ConfigDir - points to a user set directory.
type ConfigDir struct {
sync.Mutex
dir string
}

// Set - saves given directory as configuration directory.
func (config *ConfigDir) Set(dir string) {
config.Lock()
defer config.Unlock()

config.dir = dir
}

// Get - returns current configuration directory.
func (config *ConfigDir) Get() string {
config.Lock()
defer config.Unlock()

return config.dir
}

func (config *ConfigDir) getCertsDir() string {
return filepath.Join(config.Get(), certsDir)
}

// GetCADir - returns certificate CA directory.
func (config *ConfigDir) GetCADir() string {
return filepath.Join(config.getCertsDir(), certsCADir)
}

// Create - creates configuration directory tree.
func (config *ConfigDir) Create() error {
err := os.MkdirAll(config.GetCADir(), 0700)
// It is possible in kubernetes like deployments this directory
// is already mounted and is not writable, ignore any write errors.
if err != nil {
if os.IsPermission(err) {
err = nil
}
}
return err
}

// GetMinioConfigFile - returns absolute path of config.json file.
func (config *ConfigDir) GetMinioConfigFile() string {
return filepath.Join(config.Get(), minioConfigFile)
}

// GetPublicCertFile - returns absolute path of public.crt file.
func (config *ConfigDir) GetPublicCertFile() string {
return filepath.Join(config.getCertsDir(), publicCertFile)
}

// GetPrivateKeyFile - returns absolute path of private.key file.
func (config *ConfigDir) GetPrivateKeyFile() string {
return filepath.Join(config.getCertsDir(), privateKeyFile)
path string
}

func getDefaultConfigDir() string {
Expand All @@ -109,32 +54,54 @@ func getDefaultConfigDir() string {
return filepath.Join(homeDir, defaultMinioConfigDir)
}

var configDir = &ConfigDir{dir: getDefaultConfigDir()}

func setConfigDir(dir string) {
configDir.Set(dir)
func getDefaultCertsDir() string {
return filepath.Join(getDefaultConfigDir(), certsDir)
}

func getConfigDir() string {
return configDir.Get()
func getDefaultCertsCADir() string {
return filepath.Join(getDefaultCertsDir(), certsCADir)
}

func getCADir() string {
return configDir.GetCADir()
var (
// Default config, certs and CA directories.
defaultConfigDir = &ConfigDir{path: getDefaultConfigDir()}
defaultCertsDir = &ConfigDir{path: getDefaultCertsDir()}
defaultCertsCADir = &ConfigDir{path: getDefaultCertsCADir()}

// Points to current configuration directory -- deprecated, to be removed in future.
globalConfigDir = defaultConfigDir
// Points to current certs directory set by user with --certs-dir
globalCertsDir = defaultCertsDir
// Points to relative path to certs directory and is <value-of-certs-dir>/CAs
globalCertsCADir = defaultCertsCADir
)

// Get - returns current directory.
func (dir *ConfigDir) Get() string {
return dir.path
}

func createConfigDir() error {
return configDir.Create()
// Attempts to create all directories, ignores any permission denied errors.
func mkdirAllIgnorePerm(path string) error {
err := os.MkdirAll(path, 0700)
if err != nil {
// It is possible in kubernetes like deployments this directory
// is already mounted and is not writable, ignore any write errors.
if os.IsPermission(err) {
err = nil
}
}
return err
}

func getConfigFile() string {
return configDir.GetMinioConfigFile()
return filepath.Join(globalConfigDir.Get(), minioConfigFile)
}

func getPublicCertFile() string {
return configDir.GetPublicCertFile()
return filepath.Join(globalCertsDir.Get(), publicCertFile)
}

func getPrivateKeyFile() string {
return configDir.GetPrivateKeyFile()
return filepath.Join(globalCertsDir.Get(), privateKeyFile)
}
2 changes: 1 addition & 1 deletion cmd/config-migrate.go
Expand Up @@ -231,7 +231,7 @@ func migrateConfig() error {

// Version '1' is not supported anymore and deprecated, safe to delete.
func purgeV1() error {
configFile := filepath.Join(getConfigDir(), "fsUsers.json")
configFile := filepath.Join(globalConfigDir.Get(), "fsUsers.json")

cv1 := &configV1{}
_, err := Load(configFile, cv1)
Expand Down
13 changes: 8 additions & 5 deletions cmd/config-migrate_test.go
Expand Up @@ -39,7 +39,7 @@ func TestServerConfigMigrateV1(t *testing.T) {
t.Fatal(err)
}
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)
globalConfigDir = &ConfigDir{path: rootPath}

globalObjLayerMutex.Lock()
globalObjectAPI = objLayer
Expand Down Expand Up @@ -77,7 +77,7 @@ func TestServerConfigMigrateInexistentConfig(t *testing.T) {
}
defer os.RemoveAll(rootPath)

setConfigDir(rootPath)
globalConfigDir = &ConfigDir{path: rootPath}

if err := migrateV2ToV3(); err != nil {
t.Fatal("migrate v2 to v3 should succeed when no config file is found")
Expand Down Expand Up @@ -166,7 +166,8 @@ func TestServerConfigMigrateV2toV33(t *testing.T) {
t.Fatal(err)
}
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)

globalConfigDir = &ConfigDir{path: rootPath}

objLayer, fsDir, err := prepareFS()
if err != nil {
Expand Down Expand Up @@ -235,7 +236,8 @@ func TestServerConfigMigrateFaultyConfig(t *testing.T) {
t.Fatal(err)
}
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)

globalConfigDir = &ConfigDir{path: rootPath}
configPath := rootPath + "/" + minioConfigFile

// Create a corrupted config file
Expand Down Expand Up @@ -331,7 +333,8 @@ func TestServerConfigMigrateCorruptedConfig(t *testing.T) {
t.Fatal(err)
}
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)

globalConfigDir = &ConfigDir{path: rootPath}
configPath := rootPath + "/" + minioConfigFile

for i := 3; i <= 17; i++ {
Expand Down
5 changes: 1 addition & 4 deletions cmd/gateway-main.go
Expand Up @@ -124,16 +124,13 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
// To avoid this error situation we check for port availability.
logger.FatalIf(checkPortAvailability(globalMinioPort), "Unable to start the gateway")

// Create certs path.
logger.FatalIf(createConfigDir(), "Unable to create configuration directories")

// Check and load TLS certificates.
var err error
globalPublicCerts, globalTLSCerts, globalIsSSL, err = getTLSConfig()
logger.FatalIf(err, "Invalid TLS certificate file")

// Check and load Root CAs.
globalRootCAs, err = getRootCAs(getCADir())
globalRootCAs, err = getRootCAs(globalCertsCADir.Get())
logger.FatalIf(err, "Failed to read root CAs (%v)", err)

// Handle common env vars.
Expand Down
15 changes: 7 additions & 8 deletions cmd/main.go
Expand Up @@ -31,14 +31,13 @@ import (
var globalFlags = []cli.Flag{
cli.StringFlag{
Name: "config-dir, C",
Value: getConfigDir(),
Usage: func() string {
usage := "Path to configuration directory."
if getConfigDir() == "" {
usage = usage + " This option must be set."
}
return usage
}(),
Value: defaultConfigDir.Get(),
Usage: "[DEPRECATED] Path to legacy configuration directory.",
},
cli.StringFlag{
Name: "certs-dir, S",
Value: defaultCertsDir.Get(),
Usage: "Path to certs directory.",
harshavardhana marked this conversation as resolved.
Show resolved Hide resolved
},
cli.BoolFlag{
Name: "quiet",
Expand Down
5 changes: 1 addition & 4 deletions cmd/server-main.go
Expand Up @@ -207,16 +207,13 @@ func serverMain(ctx *cli.Context) {
// Handle all server command args.
serverHandleCmdArgs(ctx)

// Create certs path.
logger.FatalIf(createConfigDir(), "Unable to initialize configuration files")

// Check and load TLS certificates.
var err error
globalPublicCerts, globalTLSCerts, globalIsSSL, err = getTLSConfig()
logger.FatalIf(err, "Unable to load the TLS configuration")

// Check and load Root CAs.
globalRootCAs, err = getRootCAs(getCADir())
globalRootCAs, err = getRootCAs(globalCertsCADir.Get())
logger.FatalIf(err, "Failed to read root CAs (%v)", err)

// Handle all server environment vars.
Expand Down
2 changes: 1 addition & 1 deletion cmd/test-utils_test.go
Expand Up @@ -404,7 +404,7 @@ func StartTestServer(t TestErrHandler, instanceType string) TestServer {

// Sets the global config path to empty string.
func resetGlobalConfigPath() {
setConfigDir("")
globalConfigDir = &ConfigDir{path: ""}
}

// sets globalObjectAPI to `nil`.
Expand Down