Prevent minio server starting in standalone erasure mode for wrong inputs. (#4700)

It is possible at times due to a typo when distributed mode was intended
a user might end up starting standalone erasure mode causing confusion.
Add code to check this based on some standard heuristic guess work and
report an error to the user.

Fixes #4686
This commit is contained in:
Dee Koder 2017-08-10 16:54:19 -07:00 committed by Harshavardhana
parent 3544e5ad01
commit 1978b9d8f9
4 changed files with 38 additions and 1 deletions

View File

@ -132,6 +132,12 @@ func NewEndpoint(arg string) (ep Endpoint, e error) {
return ep, err
}
} else {
// Only check if the arg is an ip address and ask for scheme since its absent.
// localhost, example.com, any FQDN cannot be disambiguated from a regular file path such as
// /mnt/export1. So we go ahead and start the minio server in FS modes in these cases.
if isHostIPv4(arg) {
return ep, fmt.Errorf("invalid URL endpoint format: missing scheme http or https")
}
u = &url.URL{Path: path.Clean(arg)}
isLocal = true
}
@ -212,7 +218,6 @@ func NewEndpointList(args ...string) (endpoints EndpointList, err error) {
return nil, fmt.Errorf("duplicate endpoints found")
}
uniqueArgs.Add(arg)
endpoints = append(endpoints, endpoint)
}
@ -267,6 +272,7 @@ func CreateEndpoints(serverAddr string, args ...string) (string, EndpointList, S
localEndpointCount := 0
localServerAddrSet := set.NewStringSet()
localPortSet := set.NewStringSet()
for _, endpoint := range endpoints {
endpointPathSet.Add(endpoint.Path)
if endpoint.IsLocal {

View File

@ -70,6 +70,7 @@ func TestNewEndpoint(t *testing.T) {
{"http://server:8080//", Endpoint{}, -1, fmt.Errorf("empty or root path is not supported in URL endpoint")},
{"http://server:8080/", Endpoint{}, -1, fmt.Errorf("empty or root path is not supported in URL endpoint")},
{"http://server/path", Endpoint{}, -1, fmt.Errorf("lookup server" + errMsg)},
{"192.168.1.210:9000", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format: missing scheme http or https")},
}
for _, testCase := range testCases {
@ -122,6 +123,7 @@ func TestNewEndpointList(t *testing.T) {
{[]string{"ftp://server/d1", "http://server/d2", "http://server/d3", "http://server/d4"}, fmt.Errorf("'ftp://server/d1': invalid URL endpoint format")},
{[]string{"d1", "http://localhost/d2", "d3", "d4"}, fmt.Errorf("mixed style endpoints are not supported")},
{[]string{"http://example.org/d1", "https://example.com/d1", "http://example.net/d1", "https://example.edut/d1"}, fmt.Errorf("mixed scheme is not supported")},
{[]string{"192.168.1.210:9000/tmp/dir0", "192.168.1.210:9000/tmp/dir1", "192.168.1.210:9000/tmp/dir2", "192.168.110:9000/tmp/dir3"}, fmt.Errorf("'192.168.1.210:9000/tmp/dir0': invalid URL endpoint format: missing scheme http or https")},
}
for _, testCase := range testCases {

View File

@ -153,6 +153,15 @@ func getAPIEndpoints(serverAddr string) (apiEndpoints []string) {
return apiEndpoints
}
// isHostIPv4 - helper for validating if the provided arg is an ip address.
func isHostIPv4(ipAddress string) bool {
host, _, err := net.SplitHostPort(ipAddress)
if err != nil {
host = ipAddress
}
return net.ParseIP(host) != nil
}
// checkPortAvailability - check if given port is already in use.
// Note: The check method tries to listen on given port and closes it.
// It is possible to have a disconnected client in this tiny window of time.

View File

@ -317,3 +317,23 @@ func TestSameLocalAddrs(t *testing.T) {
}
}
}
func TestIsHostIPv4(t *testing.T) {
testCases := []struct {
args string
expectedResult bool
}{
{"localhost", false},
{"localhost:9000", false},
{"example.com", false},
{"http://192.168.1.0", false},
{"http://192.168.1.0:9000", false},
{"192.168.1.0", true},
}
for _, testCase := range testCases {
ret := isHostIPv4(testCase.args)
if testCase.expectedResult != ret {
t.Fatalf("expected: %v , got: %v", testCase.expectedResult, ret)
}
}
}