Compare commits

..

16 Commits

Author SHA1 Message Date
Nitish Tiwari 5afd856355 Update Kubernetes TLS doc with info for distributed setups (#5971)
Also, add details on how to create wildcard self-signed certificates
using openssl
2018-05-23 20:41:25 -07:00
Harshavardhana 000e360196 Deprecate showing drive capacity and total free (#5976)
This addresses a situation that we shouldn't be
displaying Total/Free anymore, instead we should simply
show the total usage.
2018-05-23 17:30:25 -07:00
Harshavardhana e6ec645035 Implement support for calculating disk usage per tenant (#5969)
Fixes #5961
2018-05-23 15:41:29 +05:30
Acid Chicken (硫酸鶏) 483fe4bed5 Fix typo (#5960) 2018-05-22 08:09:30 +05:30
Harshavardhana 71c4ff9d10 Fix tabs/indents in help message (#5962) 2018-05-21 11:11:57 -07:00
Harshavardhana ac58283001 Support endpoints through env (#5952) 2018-05-18 17:51:03 -07:00
Andreas Auernhammer 9c8b7306f5 security: fix write-to-RAM DoS vulnerability (#5957)
This commit fixes a DoS vulnerability for certain APIs using
signature V4 by verifying the content-md5 and/or content-sha56 of
the request body in a streaming mode.

The issue was caused by reading the entire body of the request into
memory to verify the content-md5 or content-sha56 checksum if present.

The vulnerability could be exploited by either replaying a V4 request
(in the 15 min time frame) or sending a V4 presigned request with a
large body.
2018-05-18 11:27:25 -07:00
rawipfel 1cf381f1b0 handle Kubernetes read-only secrets (#5951) 2018-05-18 10:31:11 +05:30
kannappanr ffa6b45d00 Remove treewalk abort log message (#5953)
Log doesn't add any value and can be removed.

Fixes #5943
2018-05-17 17:26:16 -07:00
Bala FA 4eb788df79 rename checkPathValid() to getValidPath() (#5949) 2018-05-17 07:27:07 -07:00
Minio Trusted f9e8ac429e Update yaml files to latest version RELEASE.2018-05-16T23-35-33Z 2018-05-16 23:39:52 +00:00
Harshavardhana 64288d6eb5 fix: export policy.Resource for remote RPC policy updates (#5941)
This PR fixes a regression where the remote bucket policies
were not updated due to policy.Resource not having exported
fields, gob fails with unexported fields while marshalling.
2018-05-16 16:17:00 -07:00
Nitish Tiwari 41496e1406 Fix broken healthcheck link (#5935) 2018-05-16 14:43:25 -07:00
Nitish Tiwari e6ebcc4cb6 Remove redundant prometheus data points (#5934)
Removed field minio_http_requests_total as it was redundant with
minio_http_requests_duration_seconds_count

Also removed field minio_server_start_time_seconds as it was
redundant with process_start_time_seconds
2018-05-15 12:23:43 -07:00
Nitish Tiwari 9cab0f25e0 Add top level metrics document to summarize monitoring endpoints (#5923)
Minio server supports healthcheck and prometheus related
unauthenticated endpoints. This document summarizes this
information in a single place and add links for more detailed
documentation if needed.
2018-05-15 12:23:21 -07:00
Minio Trusted 5c21e89559 Update yaml files to latest version RELEASE.2018-05-11T00-29-24Z 2018-05-11 00:34:18 +00:00
65 changed files with 610 additions and 518 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
Start by forking the Minio GitHub repository, make changes in a branch and then send a pull request. We encourage pull requests to discuss code changes. Here are the steps in details:
### Setup your Minio Github Repository
### Setup your Minio GitHub Repository
Fork [Minio upstream](https://github.com/minio/minio/fork) source repository to your own personal repository. Copy the URL of your Minio fork (you will need it for the `git clone` command below).
```sh
+1 -1
View File
@@ -1,6 +1,6 @@
# For maintainers only
### Setup your minio Github Repository
### Setup your minio GitHub Repository
Fork [minio upstream](https://github.com/minio/minio/fork) source repository to your own personal repository.
```bash
+1 -1
View File
@@ -89,7 +89,7 @@ export class BrowserDropdown extends React.Component {
<Dropdown.Menu className="dropdown-menu-right">
<li>
<a target="_blank" href="https://github.com/minio/minio">
Github <i className="fa fa-github" />
GitHub <i className="fa fa-github" />
</a>
</li>
<li>
+4 -11
View File
@@ -25,23 +25,16 @@ export class StorageInfo extends React.Component {
fetchStorageInfo()
}
render() {
const { total, free } = this.props.storageInfo
const used = total - free
const usedPercent = used / total * 100 + "%"
const freePercent = free * 100 / total
const { used } = this.props.storageInfo
return (
<div className="feh-usage">
<div className="feh-used">
<div className="fehu-chart">
<div style={{ width: usedPercent }} />
<div style={{ width: 0 }} />
</div>
<ul>
<li>
<span>Used: </span>
{humanize.filesize(total - free)}
</li>
<li className="pull-right">
<span>Free: </span>
{humanize.filesize(total - used)}
{humanize.filesize(used)}
</li>
</ul>
</div>
@@ -22,7 +22,7 @@ describe("StorageInfo", () => {
it("should render without crashing", () => {
shallow(
<StorageInfo
storageInfo={{ total: 100, free: 60 }}
storageInfo={{ used: 60 }}
fetchStorageInfo={jest.fn()}
/>
)
@@ -32,7 +32,7 @@ describe("StorageInfo", () => {
const fetchStorageInfo = jest.fn()
shallow(
<StorageInfo
storageInfo={{ total: 100, free: 60 }}
storageInfo={{ used: 60 }}
fetchStorageInfo={fetchStorageInfo}
/>
)
@@ -20,7 +20,7 @@ import * as actionsCommon from "../actions"
jest.mock("../../web", () => ({
StorageInfo: jest.fn(() => {
return Promise.resolve({ storageInfo: { Total: 100, Free: 60 } })
return Promise.resolve({ storageInfo: { Used: 60 } })
}),
ServerInfo: jest.fn(() => {
return Promise.resolve({
@@ -40,7 +40,7 @@ describe("Common actions", () => {
it("creates common/SET_STORAGE_INFO after fetching the storage details ", () => {
const store = mockStore()
const expectedActions = [
{ type: "common/SET_STORAGE_INFO", storageInfo: { total: 100, free: 60 } }
{ type: "common/SET_STORAGE_INFO", storageInfo: { used: 60 } }
]
return store.dispatch(actionsCommon.fetchStorageInfo()).then(() => {
const actions = store.getActions()
+1 -1
View File
@@ -34,7 +34,7 @@ export const fetchStorageInfo = () => {
return web.StorageInfo().then(res => {
const storageInfo = {
total: res.storageInfo.Total,
free: res.storageInfo.Free
used: res.storageInfo.Used
}
dispatch(setStorageInfo(storageInfo))
})
+2 -2
View File
@@ -44,9 +44,9 @@
/*--------------------------
Disk usage
Disk used
----------------------------*/
.feh-usage {
.feh-used {
margin-top: 12px;
max-width: 285px;
+24 -24
View File
File diff suppressed because one or more lines are too long
-3
View File
@@ -929,9 +929,6 @@ func TestAdminServerInfo(t *testing.T) {
if serverInfo.Error != "" {
t.Errorf("Unexpected error = %v\n", serverInfo.Error)
}
if serverInfo.Data.StorageInfo.Free == 0 {
t.Error("Expected StorageInfo.Free to be non empty")
}
if serverInfo.Data.Properties.Region != globalMinioDefaultRegion {
t.Errorf("Expected %s, got %s", globalMinioDefaultRegion, serverInfo.Data.Properties.Region)
}
+34 -47
View File
@@ -28,6 +28,7 @@ import (
"strings"
"github.com/minio/minio/cmd/logger"
"github.com/minio/minio/pkg/hash"
"github.com/minio/minio/pkg/policy"
)
@@ -209,59 +210,45 @@ func reqSignatureV4Verify(r *http.Request, region string) (s3Error APIErrorCode)
// Verify if request has valid AWS Signature Version '4'.
func isReqAuthenticated(r *http.Request, region string) (s3Error APIErrorCode) {
if r == nil {
return ErrInternalError
}
if errCode := reqSignatureV4Verify(r, region); errCode != ErrNone {
return errCode
}
payload, err := ioutil.ReadAll(r.Body)
var (
err error
contentMD5, contentSHA256 []byte
)
// Extract 'Content-Md5' if present.
if _, ok := r.Header["Content-Md5"]; ok {
contentMD5, err = base64.StdEncoding.Strict().DecodeString(r.Header.Get("Content-Md5"))
if err != nil || len(contentMD5) == 0 {
return ErrInvalidDigest
}
}
// Extract either 'X-Amz-Content-Sha256' header or 'X-Amz-Content-Sha256' query parameter (if V4 presigned)
// Do not verify 'X-Amz-Content-Sha256' if skipSHA256.
if skipSHA256 := skipContentSha256Cksum(r); !skipSHA256 && isRequestPresignedSignatureV4(r) {
if sha256Sum, ok := r.URL.Query()["X-Amz-Content-Sha256"]; ok && len(sha256Sum) > 0 {
contentSHA256, err = hex.DecodeString(sha256Sum[0])
if err != nil {
return ErrContentSHA256Mismatch
}
}
} else if _, ok := r.Header["X-Amz-Content-Sha256"]; !skipSHA256 && ok {
contentSHA256, err = hex.DecodeString(r.Header.Get("X-Amz-Content-Sha256"))
if err != nil || len(contentSHA256) == 0 {
return ErrContentSHA256Mismatch
}
}
// Verify 'Content-Md5' and/or 'X-Amz-Content-Sha256' if present.
// The verification happens implicit during reading.
reader, err := hash.NewReader(r.Body, -1, hex.EncodeToString(contentMD5), hex.EncodeToString(contentSHA256))
if err != nil {
logger.LogIf(context.Background(), err)
return ErrInternalError
}
// Populate back the payload.
r.Body = ioutil.NopCloser(bytes.NewReader(payload))
// Verify Content-Md5, if payload is set.
if clntMD5B64, ok := r.Header["Content-Md5"]; ok {
if clntMD5B64[0] == "" {
return ErrInvalidDigest
}
md5Sum, err := base64.StdEncoding.Strict().DecodeString(clntMD5B64[0])
if err != nil {
return ErrInvalidDigest
}
if !bytes.Equal(md5Sum, getMD5Sum(payload)) {
return ErrBadDigest
}
}
if skipContentSha256Cksum(r) {
return ErrNone
}
// Verify that X-Amz-Content-Sha256 Header == sha256(payload)
// If X-Amz-Content-Sha256 header is not sent then we don't calculate/verify sha256(payload)
sumHex, ok := r.Header["X-Amz-Content-Sha256"]
if isRequestPresignedSignatureV4(r) {
sumHex, ok = r.URL.Query()["X-Amz-Content-Sha256"]
}
if ok {
if sumHex[0] == "" {
return ErrContentSHA256Mismatch
}
sum, err := hex.DecodeString(sumHex[0])
if err != nil {
return ErrContentSHA256Mismatch
}
if !bytes.Equal(sum, getSHA256Sum(payload)) {
return ErrContentSHA256Mismatch
}
return toAPIErrorCode(err)
}
r.Body = ioutil.NopCloser(reader)
return ErrNone
}
+5 -4
View File
@@ -19,6 +19,7 @@ package cmd
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
@@ -361,8 +362,6 @@ func TestIsReqAuthenticated(t *testing.T) {
req *http.Request
s3Error APIErrorCode
}{
// When request is nil, internal error is returned.
{nil, ErrInternalError},
// When request is unsigned, access denied is returned.
{mustNewRequest("GET", "http://127.0.0.1:9000", 0, nil, t), ErrAccessDenied},
// Empty Content-Md5 header.
@@ -376,9 +375,11 @@ func TestIsReqAuthenticated(t *testing.T) {
}
// Validates all testcases.
for _, testCase := range testCases {
for i, testCase := range testCases {
if s3Error := isReqAuthenticated(testCase.req, globalServerConfig.GetRegion()); s3Error != testCase.s3Error {
t.Fatalf("Unexpected s3error returned wanted %d, got %d", testCase.s3Error, s3Error)
if _, err := ioutil.ReadAll(testCase.req.Body); toAPIErrorCode(err) != testCase.s3Error {
t.Fatalf("Test %d: Unexpected S3 error: want %d - got %d (got after reading request %d)", i, testCase.s3Error, s3Error, toAPIErrorCode(err))
}
}
}
}
+1 -1
View File
@@ -777,7 +777,7 @@ func (c cacheObjects) StorageInfo(ctx context.Context) (storageInfo StorageInfo)
if cfs == nil {
continue
}
info, err := getDiskInfo((cfs.fsPath))
info, err := getDiskInfo(cfs.fsPath)
logger.GetReqInfo(ctx).AppendTags("cachePath", cfs.fsPath)
logger.LogIf(ctx, err)
total += info.Total
+59
View File
@@ -0,0 +1,59 @@
/*
* Minio Cloud Storage, (C) 2018 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmd
import (
"context"
"time"
)
const (
usageCheckInterval = 12 * time.Hour // 12 hours
)
// getDiskUsage walks the file tree rooted at root, calling usageFn
// for each file or directory in the tree, including root.
func getDiskUsage(ctx context.Context, root string, usageFn usageFunc) error {
return walk(ctx, root+slashSeparator, usageFn)
}
type usageFunc func(ctx context.Context, entry string) error
// walk recursively descends path, calling walkFn.
func walk(ctx context.Context, path string, usageFn usageFunc) error {
if err := usageFn(ctx, path); err != nil {
return err
}
if !hasSuffix(path, slashSeparator) {
return nil
}
entries, err := readDir(path)
if err != nil {
return usageFn(ctx, path)
}
for _, entry := range entries {
fname := pathJoin(path, entry)
if err = walk(ctx, fname, usageFn); err != nil {
return err
}
}
return nil
}
+1 -1
View File
@@ -80,7 +80,7 @@ func TestNewMultipartUploadFaultyDisk(t *testing.T) {
}
// Test with disk removed.
fs.fsPath = filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
os.RemoveAll(disk)
if _, err := fs.NewMultipartUpload(context.Background(), bucketName, objectName, map[string]string{"X-Amz-Meta-xid": "3f"}); err != nil {
if !isSameType(err, BucketNotFound{}) {
t.Fatal("Unexpected error ", err)
+64 -9
View File
@@ -26,6 +26,7 @@ import (
"sort"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/minio/minio/cmd/logger"
@@ -63,6 +64,10 @@ type FSObjects struct {
// To manage the appendRoutine go-routines
nsMutex *nsLockMap
// Disk usage metrics
totalUsed uint64
usageCheckInterval time.Duration
}
// Represents the background append file.
@@ -102,7 +107,7 @@ func NewFSObjectLayer(fsPath string) (ObjectLayer, error) {
}
var err error
if fsPath, err = checkPathValid(fsPath); err != nil {
if fsPath, err = getValidPath(fsPath); err != nil {
return nil, uiErrUnableToWriteInBackend(err)
}
@@ -129,9 +134,10 @@ func NewFSObjectLayer(fsPath string) (ObjectLayer, error) {
rwPool: &fsIOPool{
readersMap: make(map[string]*lock.RLockedFile),
},
nsMutex: newNSLock(false),
listPool: newTreeWalkPool(globalLookupTimeout),
appendFileMap: make(map[string]*fsAppendFile),
nsMutex: newNSLock(false),
listPool: newTreeWalkPool(globalLookupTimeout),
appendFileMap: make(map[string]*fsAppendFile),
usageCheckInterval: usageCheckInterval,
}
// Once the filesystem has initialized hold the read lock for
@@ -150,6 +156,7 @@ func NewFSObjectLayer(fsPath string) (ObjectLayer, error) {
return nil, uiErrUnableToReadFromBackend(err).Msg("Unable to initialize policy system")
}
go fs.diskUsage(globalServiceDoneCh)
go fs.cleanupStaleMultipartUploads(ctx, globalMultipartCleanupInterval, globalMultipartExpiry, globalServiceDoneCh)
// Return successfully initialized object layer.
@@ -164,14 +171,62 @@ func (fs *FSObjects) Shutdown(ctx context.Context) error {
return fsRemoveAll(ctx, pathJoin(fs.fsPath, minioMetaTmpBucket, fs.fsUUID))
}
// diskUsage returns du information for the posix path, in a continuous routine.
func (fs *FSObjects) diskUsage(doneCh chan struct{}) {
ticker := time.NewTicker(fs.usageCheckInterval)
defer ticker.Stop()
usageFn := func(ctx context.Context, entry string) error {
var fi os.FileInfo
var err error
if hasSuffix(entry, slashSeparator) {
fi, err = fsStatDir(ctx, entry)
} else {
fi, err = fsStatFile(ctx, entry)
}
if err != nil {
return err
}
atomic.AddUint64(&fs.totalUsed, uint64(fi.Size()))
return nil
}
if err := getDiskUsage(context.Background(), fs.fsPath, usageFn); err != nil {
return
}
for {
select {
case <-doneCh:
return
case <-ticker.C:
var usage uint64
usageFn = func(ctx context.Context, entry string) error {
var fi os.FileInfo
var err error
if hasSuffix(entry, slashSeparator) {
fi, err = fsStatDir(ctx, entry)
} else {
fi, err = fsStatFile(ctx, entry)
}
if err != nil {
return err
}
usage = usage + uint64(fi.Size())
return nil
}
if err := getDiskUsage(context.Background(), fs.fsPath, usageFn); err != nil {
continue
}
atomic.StoreUint64(&fs.totalUsed, usage)
}
}
}
// StorageInfo - returns underlying storage statistics.
func (fs *FSObjects) StorageInfo(ctx context.Context) StorageInfo {
info, err := getDiskInfo((fs.fsPath))
logger.GetReqInfo(ctx).AppendTags("path", fs.fsPath)
logger.LogIf(ctx, err)
storageInfo := StorageInfo{
Total: info.Total,
Free: info.Free,
Used: atomic.LoadUint64(&fs.totalUsed),
}
storageInfo.Backend.Type = FS
return storageInfo
+5 -4
View File
@@ -33,6 +33,11 @@ import (
"github.com/minio/minio/cmd/logger"
)
func init() {
logger.Init(GOPATH)
logger.RegisterUIError(fmtError)
}
var (
gatewayCmd = cli.Command{
Name: "gateway",
@@ -102,10 +107,6 @@ func ValidateGatewayArguments(serverAddr, endpointAddr string) error {
return nil
}
func init() {
logger.Init(GOPATH)
}
// StartGateway - handler for 'minio gateway <name>'.
func StartGateway(ctx *cli.Context, gw Gateway) {
if gw == nil {
+15 -19
View File
@@ -75,36 +75,32 @@ ENVIRONMENT VARIABLES:
BROWSER:
MINIO_BROWSER: To disable web browser access, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
CACHE:
MINIO_CACHE_DRIVES: List of mounted drives or directories delimited by ";".
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
UPDATE:
MINIO_UPDATE: To turn off in-place upgrades, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
EXAMPLES:
1. Start minio gateway server for Azure Blob Storage backend.
$ export MINIO_ACCESS_KEY=azureaccountname
$ export MINIO_SECRET_KEY=azureaccountkey
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=azureaccountname
$ export MINIO_SECRET_KEY=azureaccountkey
$ {{.HelpName}}
2. Start minio gateway server for Azure Blob Storage backend on custom endpoint.
$ export MINIO_ACCESS_KEY=azureaccountname
$ export MINIO_SECRET_KEY=azureaccountkey
$ {{.HelpName}} https://azure.example.com
$ export MINIO_ACCESS_KEY=azureaccountname
$ export MINIO_SECRET_KEY=azureaccountkey
$ {{.HelpName}} https://azure.example.com
3. Start minio gateway server for Azure Blob Storage backend with edge caching enabled.
$ export MINIO_ACCESS_KEY=azureaccountname
$ export MINIO_SECRET_KEY=azureaccountkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=azureaccountname
$ export MINIO_SECRET_KEY=azureaccountkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
`
minio.RegisterGatewayCommand(cli.Command{
+12 -15
View File
@@ -65,30 +65,27 @@ ENVIRONMENT VARIABLES:
BROWSER:
MINIO_BROWSER: To disable web browser access, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
CACHE:
MINIO_CACHE_DRIVES: List of mounted drives or directories delimited by ";".
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
UPDATE:
MINIO_UPDATE: To turn off in-place upgrades, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
EXAMPLES:
1. Start minio gateway server for B2 backend.
$ export MINIO_ACCESS_KEY=accountID
$ export MINIO_SECRET_KEY=applicationKey
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=accountID
$ export MINIO_SECRET_KEY=applicationKey
$ {{.HelpName}}
2. Start minio gateway server for B2 backend with edge caching enabled.
$ export MINIO_ACCESS_KEY=accountID
$ export MINIO_SECRET_KEY=applicationKey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=accountID
$ export MINIO_SECRET_KEY=applicationKey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
`
minio.RegisterGatewayCommand(cli.Command{
Name: b2Backend,
+15 -18
View File
@@ -111,36 +111,33 @@ ENVIRONMENT VARIABLES:
BROWSER:
MINIO_BROWSER: To disable web browser access, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
CACHE:
MINIO_CACHE_DRIVES: List of mounted drives or directories delimited by ";".
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
UPDATE:
MINIO_UPDATE: To turn off in-place upgrades, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
GCS credentials file:
GOOGLE_APPLICATION_CREDENTIALS: Path to credentials.json
EXAMPLES:
1. Start minio gateway server for GCS backend.
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
(Instructions to generate credentials : https://developers.google.com/identity/protocols/application-default-credentials)
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ {{.HelpName}} mygcsprojectid
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
(Instructions to generate credentials : https://developers.google.com/identity/protocols/application-default-credentials)
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ {{.HelpName}} mygcsprojectid
2. Start minio gateway server for GCS backend with edge caching enabled.
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}} mygcsprojectid
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}} mygcsprojectid
`
minio.RegisterGatewayCommand(cli.Command{
+16 -16
View File
@@ -81,28 +81,28 @@ ENVIRONMENT VARIABLES:
EXAMPLES:
1. Start minio gateway server for Manta Object Storage backend.
$ export MINIO_ACCESS_KEY=manta_account_name
$ export MINIO_SECRET_KEY=manta_key_id
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=manta_account_name
$ export MINIO_SECRET_KEY=manta_key_id
$ {{.HelpName}}
2. Start minio gateway server for Manta Object Storage backend on custom endpoint.
$ export MINIO_ACCESS_KEY=manta_account_name
$ export MINIO_SECRET_KEY=manta_key_id
$ {{.HelpName}} https://us-west.manta.joyent.com
$ export MINIO_ACCESS_KEY=manta_account_name
$ export MINIO_SECRET_KEY=manta_key_id
$ {{.HelpName}} https://us-west.manta.joyent.com
3. Start minio gateway server for Manta Object Storage backend without using SSH Agent.
$ export MINIO_ACCESS_KEY=manta_account_name
$ export MINIO_SECRET_KEY=manta_key_id
$ export MANTA_KEY_MATERIAL=~/.ssh/custom_rsa
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=manta_account_name
$ export MINIO_SECRET_KEY=manta_key_id
$ export MANTA_KEY_MATERIAL=~/.ssh/custom_rsa
$ {{.HelpName}}
4. Start minio gateway server for Manta Object Storage backend with edge caching enabled.
$ export MINIO_ACCESS_KEY=manta_account_name
$ export MINIO_SECRET_KEY=manta_key_id
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=manta_account_name
$ export MINIO_SECRET_KEY=manta_key_id
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
`
minio.RegisterGatewayCommand(cli.Command{
+13 -16
View File
@@ -40,7 +40,7 @@ FLAGS:
{{range .VisibleFlags}}{{.}}
{{end}}{{end}}
PATH:
path to NAS mount point.
Path to NAS mount point.
ENVIRONMENT VARIABLES:
ACCESS:
@@ -50,30 +50,27 @@ ENVIRONMENT VARIABLES:
BROWSER:
MINIO_BROWSER: To disable web browser access, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
CACHE:
MINIO_CACHE_DRIVES: List of mounted drives or directories delimited by ";".
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
UPDATE:
MINIO_UPDATE: To turn off in-place upgrades, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
EXAMPLES:
1. Start minio gateway server for NAS backend.
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ {{.HelpName}} /shared/nasvol
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ {{.HelpName}} /shared/nasvol
2. Start minio gateway server for NAS with edge caching enabled.
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}} /shared/nasvol
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}} /shared/nasvol
`
minio.RegisterGatewayCommand(cli.Command{
+12 -15
View File
@@ -67,9 +67,6 @@ ENVIRONMENT VARIABLES:
BROWSER:
MINIO_BROWSER: To disable web browser access, set this value to "off".
UPDATE:
MINIO_UPDATE: To turn off in-place upgrades, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
@@ -80,22 +77,22 @@ ENVIRONMENT VARIABLES:
EXAMPLES:
1. Start minio gateway server for Aliyun OSS backend.
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ {{.HelpName}}
2. Start minio gateway server for Aliyun OSS backend on custom endpoint.
$ export MINIO_ACCESS_KEY=Q3AM3UQ867SPQQA43P2F
$ export MINIO_SECRET_KEY=zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG
$ {{.HelpName}} https://oss.example.com
$ export MINIO_ACCESS_KEY=Q3AM3UQ867SPQQA43P2F
$ export MINIO_SECRET_KEY=zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG
$ {{.HelpName}} https://oss.example.com
3. Start minio gateway server for Aliyun OSS backend with edge caching enabled.
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
`
minio.RegisterGatewayCommand(cli.Command{
+15 -18
View File
@@ -58,35 +58,32 @@ ENVIRONMENT VARIABLES:
BROWSER:
MINIO_BROWSER: To disable web browser access, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
CACHE:
MINIO_CACHE_DRIVES: List of mounted drives or directories delimited by ";".
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
UPDATE:
MINIO_UPDATE: To turn off in-place upgrades, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
EXAMPLES:
1. Start minio gateway server for AWS S3 backend.
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ {{.HelpName}}
2. Start minio gateway server for S3 backend on custom endpoint.
$ export MINIO_ACCESS_KEY=Q3AM3UQ867SPQQA43P2F
$ export MINIO_SECRET_KEY=zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG
$ {{.HelpName}} https://play.minio.io:9000
$ export MINIO_ACCESS_KEY=Q3AM3UQ867SPQQA43P2F
$ export MINIO_SECRET_KEY=zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG
$ {{.HelpName}} https://play.minio.io:9000
3. Start minio gateway server for AWS S3 backend with edge caching enabled.
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
$ export MINIO_ACCESS_KEY=accesskey
$ export MINIO_SECRET_KEY=secretkey
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
`
minio.RegisterGatewayCommand(cli.Command{
+8 -11
View File
@@ -72,29 +72,26 @@ ENVIRONMENT VARIABLES: (Default values in parenthesis)
BROWSER:
MINIO_BROWSER: To disable web browser access, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
CACHE:
MINIO_CACHE_DRIVES: List of mounted drives or directories delimited by ";".
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
UPDATE:
MINIO_UPDATE: To turn off in-place upgrades, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
SIA_TEMP_DIR: The name of the local Sia temporary storage directory. (.sia_temp)
SIA_API_PASSWORD: API password for Sia daemon. (default is empty)
EXAMPLES:
1. Start minio gateway server for Sia backend.
$ {{.HelpName}}
$ {{.HelpName}}
2. Start minio gateway server for Sia backend with edge caching enabled.
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
$ export MINIO_CACHE_EXPIRY=40
$ {{.HelpName}}
`
minio.RegisterGatewayCommand(cli.Command{
-2
View File
@@ -190,8 +190,6 @@ func (st *HTTPStats) updateStats(r *http.Request, w *httpResponseRecorder, durat
st.successDELETEs.Duration.Add(durationSecs)
}
}
// Increment the prometheus http request count with appropriate label
httpRequests.With(prometheus.Labels{"request_type": r.Method}).Inc()
// Increment the prometheus http request response histogram with appropriate label
httpRequestsDuration.With(prometheus.Labels{"request_type": r.Method}).Observe(durationSecs)
}
+2 -21
View File
@@ -26,13 +26,6 @@ import (
)
var (
httpRequests = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "minio_http_requests_total",
Help: "Total number of requests served by current Minio server instance",
},
[]string{"request_type"},
)
httpRequestsDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "minio_http_requests_duration_seconds",
@@ -44,7 +37,6 @@ var (
)
func init() {
prometheus.MustRegister(httpRequests)
prometheus.MustRegister(httpRequestsDuration)
prometheus.MustRegister(newMinioCollector())
}
@@ -107,6 +99,7 @@ func (c *minioCollector) Collect(ch chan<- prometheus.Metric) {
prometheus.CounterValue,
float64(globalConnStats.getTotalInputBytes()),
)
// Total/Free Storage Bytes
ch <- prometheus.MustNewConstMetric(
prometheus.NewDesc(
@@ -124,15 +117,6 @@ func (c *minioCollector) Collect(ch chan<- prometheus.Metric) {
prometheus.GaugeValue,
float64(s.Free),
)
// Set Server Start Time
ch <- prometheus.MustNewConstMetric(
prometheus.NewDesc(
prometheus.BuildFQName("minio", "server", "start_time_seconds"),
"Time when current Minio server instance started",
nil, nil),
prometheus.GaugeValue,
float64(globalBootTime.Unix()),
)
// Minio Total Disk/Offline Disk
ch <- prometheus.MustNewConstMetric(
@@ -156,10 +140,7 @@ func (c *minioCollector) Collect(ch chan<- prometheus.Metric) {
func metricsHandler() http.Handler {
registry := prometheus.NewRegistry()
err := registry.Register(httpRequests)
logger.LogIf(context.Background(), err)
err = registry.Register(httpRequestsDuration)
err := registry.Register(httpRequestsDuration)
logger.LogIf(context.Background(), err)
err = registry.Register(newMinioCollector())
+1 -3
View File
@@ -18,8 +18,6 @@ package cmd
import (
"sync"
"github.com/minio/minio/pkg/disk"
)
// naughtyDisk wraps a POSIX disk and returns programmed errors
@@ -74,7 +72,7 @@ func (d *naughtyDisk) calcError() (err error) {
return nil
}
func (d *naughtyDisk) DiskInfo() (info disk.Info, err error) {
func (d *naughtyDisk) DiskInfo() (info DiskInfo, err error) {
if err := d.calcError(); err != nil {
return info, err
}
+4 -4
View File
@@ -39,10 +39,10 @@ const (
// StorageInfo - represents total capacity of underlying storage.
type StorageInfo struct {
// Total disk space.
Total uint64
// Free available disk space.
Free uint64
Total uint64 // Total disk space.
Free uint64 // Free available space.
Used uint64 // Used total used per tenant.
// Backend type.
Backend struct {
// Represents various backend types, currently on FS and Erasure.
+85 -4
View File
@@ -29,6 +29,7 @@ import (
"sync"
"sync/atomic"
"syscall"
"time"
humanize "github.com/dustin/go-humanize"
"github.com/minio/minio/cmd/logger"
@@ -47,6 +48,11 @@ type posix struct {
diskPath string
pool sync.Pool
connected bool
// Disk usage metrics
stopUsageCh chan struct{}
totalUsage uint64
usageCheckInterval time.Duration
}
// checkPathLength - returns error if given path name length more than 255
@@ -72,7 +78,7 @@ func checkPathLength(pathName string) error {
return nil
}
func checkPathValid(path string) (string, error) {
func getValidPath(path string) (string, error) {
if path == "" {
return path, errInvalidArgument
}
@@ -128,6 +134,7 @@ func isDirEmpty(dirname string) bool {
return false
}
defer f.Close()
// List one entry.
_, err = f.Readdirnames(1)
if err != io.EOF {
@@ -144,7 +151,7 @@ func isDirEmpty(dirname string) bool {
// Initialize a new storage disk.
func newPosix(path string) (StorageAPI, error) {
var err error
if path, err = checkPathValid(path); err != nil {
if path, err = getValidPath(path); err != nil {
return nil, err
}
@@ -157,9 +164,14 @@ func newPosix(path string) (StorageAPI, error) {
return &b
},
},
stopUsageCh: make(chan struct{}),
usageCheckInterval: usageCheckInterval,
}
st.connected = true
go st.diskUsage()
// Success.
return st, nil
}
@@ -242,6 +254,7 @@ func (s *posix) String() string {
}
func (s *posix) Close() error {
close(s.stopUsageCh)
s.connected = false
return nil
}
@@ -250,10 +263,26 @@ func (s *posix) IsOnline() bool {
return s.connected
}
// DiskInfo is an extended type which returns current
// disk usage per path.
type DiskInfo struct {
Total uint64
Free uint64
Used uint64
}
// DiskInfo provides current information about disk space usage,
// total free inodes and underlying filesystem.
func (s *posix) DiskInfo() (info disk.Info, err error) {
return getDiskInfo((s.diskPath))
func (s *posix) DiskInfo() (info DiskInfo, err error) {
di, err := getDiskInfo(s.diskPath)
if err != nil {
return info, err
}
return DiskInfo{
Total: di.Total,
Free: di.Free,
Used: atomic.LoadUint64(&s.totalUsage),
}, nil
}
// getVolDir - will convert incoming volume names to
@@ -285,6 +314,58 @@ func (s *posix) checkDiskFound() (err error) {
return err
}
// diskUsage returns du information for the posix path, in a continuous routine.
func (s *posix) diskUsage() {
ticker := time.NewTicker(s.usageCheckInterval)
defer ticker.Stop()
usageFn := func(ctx context.Context, entry string) error {
select {
case <-s.stopUsageCh:
return errWalkAbort
default:
fi, err := os.Stat(entry)
if err != nil {
return err
}
atomic.AddUint64(&s.totalUsage, uint64(fi.Size()))
return nil
}
}
if err := getDiskUsage(context.Background(), s.diskPath, usageFn); err != nil {
return
}
for {
select {
case <-s.stopUsageCh:
return
case <-globalServiceDoneCh:
return
case <-ticker.C:
var usage uint64
usageFn = func(ctx context.Context, entry string) error {
select {
case <-s.stopUsageCh:
return errWalkAbort
default:
fi, err := os.Stat(entry)
if err != nil {
return err
}
usage = usage + uint64(fi.Size())
return nil
}
}
if err := getDiskUsage(context.Background(), s.diskPath, usageFn); err != nil {
continue
}
atomic.StoreUint64(&s.totalUsage, usage)
}
}
}
// Make a volume entry.
func (s *posix) MakeVol(volume string) (err error) {
defer func() {
+39 -25
View File
@@ -22,6 +22,7 @@ import (
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"github.com/minio/cli"
@@ -30,6 +31,11 @@ import (
"github.com/minio/minio/cmd/logger"
)
func init() {
logger.Init(GOPATH)
logger.RegisterUIError(fmtError)
}
var serverFlags = []cli.Flag{
cli.StringFlag{
Name: "address",
@@ -65,6 +71,9 @@ ENVIRONMENT VARIABLES:
MINIO_ACCESS_KEY: Custom username or access key of minimum 3 characters in length.
MINIO_SECRET_KEY: Custom password or secret key of minimum 8 characters in length.
ENDPOINTS:
MINIO_ENDPOINTS: List of all endpoints delimited by ' '.
BROWSER:
MINIO_BROWSER: To disable web browser access, set this value to "off".
@@ -73,12 +82,6 @@ ENVIRONMENT VARIABLES:
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
REGION:
MINIO_REGION: To set custom region. By default all regions are accepted.
UPDATE:
MINIO_UPDATE: To turn off in-place upgrades, set this value to "off".
DOMAIN:
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
@@ -87,23 +90,24 @@ ENVIRONMENT VARIABLES:
EXAMPLES:
1. Start minio server on "/home/shared" directory.
$ {{.HelpName}} /home/shared
$ {{.HelpName}} /home/shared
2. Start minio server bound to a specific ADDRESS:PORT.
$ {{.HelpName}} --address 192.168.1.101:9000 /home/shared
$ {{.HelpName}} --address 192.168.1.101:9000 /home/shared
3. Start minio server and enable virtual-host-style requests.
$ export MINIO_DOMAIN=mydomain.com
$ {{.HelpName}} --address mydomain.com:9000 /mnt/export
$ export MINIO_DOMAIN=mydomain.com
$ {{.HelpName}} --address mydomain.com:9000 /mnt/export
4. Start minio server on 64 disks server.
$ {{.HelpName}} /mnt/export{1...64}
4. Start minio server on 64 disks server with endpoints through environment variable.
$ export MINIO_ENDPOINTS=/mnt/export{1...64}
$ {{.HelpName}}
5. Start distributed minio server on an 8 node setup with 8 drives each. Run following command on all the 8 nodes.
$ export MINIO_ACCESS_KEY=minio
$ export MINIO_SECRET_KEY=miniostorage
$ {{.HelpName}} http://node{1...8}.example.com/mnt/export/{1...8}
$ export MINIO_ACCESS_KEY=minio
$ export MINIO_SECRET_KEY=miniostorage
$ {{.HelpName}} http://node{1...8}.example.com/mnt/export/{1...8}
6. Start minio server with edge caching enabled.
$ export MINIO_CACHE_DRIVES="/mnt/drive1;/mnt/drive2;/mnt/drive3;/mnt/drive4"
$ export MINIO_CACHE_EXCLUDE="bucket1/*;*.png"
@@ -112,6 +116,16 @@ EXAMPLES:
`,
}
// Checks if endpoints are either available through environment
// or command line, returns false if both fails.
func endpointsPresent(ctx *cli.Context) bool {
_, ok := os.LookupEnv("MINIO_ENDPOINTS")
if !ok {
ok = ctx.Args().Present()
}
return ok
}
func serverHandleCmdArgs(ctx *cli.Context) {
// Handle common command args.
handleCommonCmdArgs(ctx)
@@ -124,11 +138,17 @@ func serverHandleCmdArgs(ctx *cli.Context) {
var err error
if len(ctx.Args()) > serverCommandLineArgsMax {
uErr := uiErrInvalidErasureEndpoints(nil).Msg(fmt.Sprintf("Invalid total number of endpoints (%d) passed, supported upto 32 unique arguments", len(ctx.Args())))
uErr := uiErrInvalidErasureEndpoints(nil).Msg(fmt.Sprintf("Invalid total number of endpoints (%d) passed, supported upto 32 unique arguments",
len(ctx.Args())))
logger.FatalIf(uErr, "Unable to validate passed endpoints")
}
globalMinioAddr, globalEndpoints, setupType, globalXLSetCount, globalXLSetDriveCount, err = createServerEndpoints(serverAddr, ctx.Args()...)
endpoints := strings.Fields(os.Getenv("MINIO_ENDPOINTS"))
if len(endpoints) > 0 {
globalMinioAddr, globalEndpoints, setupType, globalXLSetCount, globalXLSetDriveCount, err = createServerEndpoints(serverAddr, endpoints...)
} else {
globalMinioAddr, globalEndpoints, setupType, globalXLSetCount, globalXLSetDriveCount, err = createServerEndpoints(serverAddr, ctx.Args()...)
}
logger.FatalIf(err, "Invalid command line arguments")
globalMinioHost, globalMinioPort = mustSplitHostPort(globalMinioAddr)
@@ -158,13 +178,9 @@ func serverHandleEnvVars() {
}
func init() {
logger.Init(GOPATH)
}
// serverMain handler called for 'minio server' command.
func serverMain(ctx *cli.Context) {
if (!ctx.IsSet("sets") && !ctx.Args().Present()) || ctx.Args().First() == "help" {
if ctx.Args().First() == "help" || !endpointsPresent(ctx) {
cli.ShowCommandHelpAndExit(ctx, "server", 1)
}
@@ -185,8 +201,6 @@ func serverMain(ctx *cli.Context) {
logger.EnableQuiet()
}
logger.RegisterUIError(fmtError)
// Handle all server command args.
serverHandleCmdArgs(ctx)
+5 -5
View File
@@ -173,19 +173,19 @@ func printObjectAPIMsg() {
// Get formatted disk/storage info message.
func getStorageInfoMsg(storageInfo StorageInfo) string {
msg := fmt.Sprintf("%s %s Free, %s Total", colorBlue("Drive Capacity:"),
humanize.IBytes(uint64(storageInfo.Free)),
humanize.IBytes(uint64(storageInfo.Total)))
var msg string
if storageInfo.Backend.Type == Erasure {
diskInfo := fmt.Sprintf(" %d Online, %d Offline. ", storageInfo.Backend.OnlineDisks, storageInfo.Backend.OfflineDisks)
msg += colorBlue("\nStatus:") + fmt.Sprintf(getFormatStr(len(diskInfo), 8), diskInfo)
msg += colorBlue("Status:") + fmt.Sprintf(getFormatStr(len(diskInfo), 8), diskInfo)
}
return msg
}
// Prints startup message of storage capacity and erasure information.
func printStorageInfo(storageInfo StorageInfo) {
logger.StartupMessage(getStorageInfoMsg(storageInfo) + "\n")
if msg := getStorageInfoMsg(storageInfo); msg != "" {
logger.StartupMessage(msg)
}
}
func printCacheStorageInfo(storageInfo StorageInfo) {
+1 -5
View File
@@ -25,20 +25,16 @@ import (
"strings"
"testing"
"time"
humanize "github.com/dustin/go-humanize"
)
// Tests if we generate storage info.
func TestStorageInfoMsg(t *testing.T) {
infoStorage := StorageInfo{}
infoStorage.Total = 10 * humanize.GiByte
infoStorage.Free = 2 * humanize.GiByte
infoStorage.Backend.Type = Erasure
infoStorage.Backend.OnlineDisks = 7
infoStorage.Backend.OfflineDisks = 1
if msg := getStorageInfoMsg(infoStorage); !strings.Contains(msg, "2.0 GiB Free, 10 GiB Total") || !strings.Contains(msg, "7 Online, 1 Offline") {
if msg := getStorageInfoMsg(infoStorage); !strings.Contains(msg, "7 Online, 1 Offline") {
t.Fatal("Unexpected storage info message, found:", msg)
}
}
+1 -3
View File
@@ -18,8 +18,6 @@ package cmd
import (
"io"
"github.com/minio/minio/pkg/disk"
)
// StorageAPI interface.
@@ -30,7 +28,7 @@ type StorageAPI interface {
// Storage operations.
IsOnline() bool // Returns true if disk is online.
Close() error
DiskInfo() (info disk.Info, err error)
DiskInfo() (info DiskInfo, err error)
// Volume operations.
MakeVol(volume string) (err error)
+2 -4
View File
@@ -23,8 +23,6 @@ import (
"net/rpc"
"path"
"strings"
"github.com/minio/minio/pkg/disk"
)
type networkStorage struct {
@@ -164,10 +162,10 @@ func (n *networkStorage) call(handler string, args interface {
}
// DiskInfo - fetch disk information for a remote disk.
func (n *networkStorage) DiskInfo() (info disk.Info, err error) {
func (n *networkStorage) DiskInfo() (info DiskInfo, err error) {
args := AuthRPCArgs{}
if err = n.call("Storage.DiskInfoHandler", &args, &info); err != nil {
return disk.Info{}, err
return DiskInfo{}, err
}
return info, nil
}
+1 -2
View File
@@ -24,7 +24,6 @@ import (
"github.com/gorilla/mux"
"github.com/minio/minio/cmd/logger"
"github.com/minio/minio/pkg/disk"
)
// Storage server implements rpc primitives to facilitate exporting a
@@ -39,7 +38,7 @@ type storageServer struct {
/// Storage operations handlers.
// DiskInfoHandler - disk info handler is rpc wrapper for DiskInfo operation.
func (s *storageServer) DiskInfoHandler(args *AuthRPCArgs, reply *disk.Info) error {
func (s *storageServer) DiskInfoHandler(args *AuthRPCArgs, reply *DiskInfo) error {
if err := args.IsAuthenticated(); err != nil {
return err
}
+1 -3
View File
@@ -19,8 +19,6 @@ package cmd
import (
"os"
"testing"
"github.com/minio/minio/pkg/disk"
)
type testStorageRPCServer struct {
@@ -91,7 +89,7 @@ func TestStorageRPCInvalidToken(t *testing.T) {
Vol: "myvol",
}
// 1. DiskInfoHandler
diskInfoReply := &disk.Info{}
diskInfoReply := &DiskInfo{}
err = storageRPC.DiskInfoHandler(&badAuthRPCArgs, diskInfoReply)
errorIfInvalidToken(t, err)
-4
View File
@@ -20,8 +20,6 @@ import (
"context"
"sort"
"strings"
"github.com/minio/minio/cmd/logger"
)
// Tree walk result carries results of tree walking.
@@ -147,7 +145,6 @@ func doTreeWalk(ctx context.Context, bucket, prefixDir, entryPrefixMatch, marker
if err != nil {
select {
case <-endWalkCh:
logger.LogIf(ctx, errWalkAbort)
return errWalkAbort
case resultCh <- treeWalkResult{err: err}:
return err
@@ -229,7 +226,6 @@ func doTreeWalk(ctx context.Context, bucket, prefixDir, entryPrefixMatch, marker
isEOF := ((i == len(entries)-1) && isEnd)
select {
case <-endWalkCh:
logger.LogIf(ctx, errWalkAbort)
return errWalkAbort
case resultCh <- treeWalkResult{entry: pathJoin(prefixDir, entry), end: isEOF}:
}
+1 -1
View File
@@ -65,7 +65,7 @@ EXIT STATUS:
EXAMPLES:
1. Check and update minio:
$ {{.HelpName}}
$ {{.HelpName}}
`,
}
+1 -1
View File
@@ -36,7 +36,7 @@ FLAGS:
{{end}}{{end}}
EXAMPLES:
1. Prints server version:
$ {{.HelpName}}
$ {{.HelpName}}
`,
}
+1 -5
View File
@@ -221,13 +221,9 @@ func testStorageInfoWebHandler(obj ObjectLayer, instanceType string, t TestErrHa
if rec.Code != http.StatusOK {
t.Fatalf("Expected the response status to be 200, but instead found `%d`", rec.Code)
}
err = getTestWebRPCResponse(rec, &storageInfoReply)
if err != nil {
if err = getTestWebRPCResponse(rec, &storageInfoReply); err != nil {
t.Fatalf("Failed %v", err)
}
if storageInfoReply.StorageInfo.Total <= 0 {
t.Fatalf("Got a zero or negative total free space disk")
}
}
// Wrapper for calling ServerInfo Web Handler
+1 -2
View File
@@ -280,8 +280,7 @@ func (s *xlSets) StorageInfo(ctx context.Context) StorageInfo {
storageInfo.Backend.Type = Erasure
for _, set := range s.sets {
lstorageInfo := set.StorageInfo(ctx)
storageInfo.Total = storageInfo.Total + lstorageInfo.Total
storageInfo.Free = storageInfo.Free + lstorageInfo.Free
storageInfo.Used = storageInfo.Used + lstorageInfo.Used
storageInfo.Backend.OnlineDisks = storageInfo.Backend.OnlineDisks + lstorageInfo.Backend.OnlineDisks
storageInfo.Backend.OfflineDisks = storageInfo.Backend.OfflineDisks + lstorageInfo.Backend.OfflineDisks
}
-40
View File
@@ -98,46 +98,6 @@ func TestNewXLSets(t *testing.T) {
}
}
// TestStorageInfoSets - tests storage info for erasure coded sets of disks.
func TestStorageInfoSets(t *testing.T) {
var nDisks = 16 // Maximum disks.
var erasureDisks []string
for i := 0; i < nDisks; i++ {
// Do not attempt to create this path, the test validates
// so that newXLSets initializes non existing paths
// and successfully returns initialized object layer.
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
erasureDisks = append(erasureDisks, disk)
defer os.RemoveAll(disk)
}
endpoints := mustGetNewEndpointList(erasureDisks...)
// Initializes all erasure disks
format, err := waitForFormatXL(context.Background(), true, endpoints, 1, 16)
if err != nil {
t.Fatalf("Unable to format disks for erasure, %s", err)
}
objLayer, err := newXLSets(endpoints, format, 1, 16)
if err != nil {
t.Fatal(err)
}
// Get storage info first attempt.
disks16Info := objLayer.StorageInfo(context.Background())
// This test assumes homogeneity between all disks,
// i.e if we loose one disk the effective storage
// usage values is assumed to decrease. If we have
// heterogenous environment this is not true all the time.
if disks16Info.Free <= 0 {
t.Fatalf("Diskinfo total free values should be greater 0")
}
if disks16Info.Total <= 0 {
t.Fatalf("Diskinfo total values should be greater 0")
}
}
// TestHashedLayer - tests the hashed layer which will be returned
// consistently for a given object name.
func TestHashedLayer(t *testing.T) {
+13 -16
View File
@@ -23,7 +23,6 @@ import (
"github.com/minio/minio/cmd/logger"
"github.com/minio/minio/pkg/bpool"
"github.com/minio/minio/pkg/disk"
)
// XL constants.
@@ -118,7 +117,7 @@ func (xl xlObjects) ClearLocks(ctx context.Context, volLocks []VolumeLockInfo) e
}
// byDiskTotal is a collection satisfying sort.Interface.
type byDiskTotal []disk.Info
type byDiskTotal []DiskInfo
func (d byDiskTotal) Len() int { return len(d) }
func (d byDiskTotal) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
@@ -127,8 +126,8 @@ func (d byDiskTotal) Less(i, j int) bool {
}
// getDisksInfo - fetch disks info across all other storage API.
func getDisksInfo(disks []StorageAPI) (disksInfo []disk.Info, onlineDisks int, offlineDisks int) {
disksInfo = make([]disk.Info, len(disks))
func getDisksInfo(disks []StorageAPI) (disksInfo []DiskInfo, onlineDisks int, offlineDisks int) {
disksInfo = make([]DiskInfo, len(disks))
for i, storageDisk := range disks {
if storageDisk == nil {
// Storage disk is empty, perhaps ignored disk or not available.
@@ -154,8 +153,8 @@ func getDisksInfo(disks []StorageAPI) (disksInfo []disk.Info, onlineDisks int, o
// returns sorted disksInfo slice which has only valid entries.
// i.e the entries where the total size of the disk is not stated
// as 0Bytes, this means that the disk is not online or ignored.
func sortValidDisksInfo(disksInfo []disk.Info) []disk.Info {
var validDisksInfo []disk.Info
func sortValidDisksInfo(disksInfo []DiskInfo) []DiskInfo {
var validDisksInfo []DiskInfo
for _, diskInfo := range disksInfo {
if diskInfo.Total == 0 {
continue
@@ -174,10 +173,7 @@ func getStorageInfo(disks []StorageAPI) StorageInfo {
validDisksInfo := sortValidDisksInfo(disksInfo)
// If there are no valid disks, set total and free disks to 0
if len(validDisksInfo) == 0 {
return StorageInfo{
Total: 0,
Free: 0,
}
return StorageInfo{}
}
_, sscParity := getRedundancyCount(standardStorageClass, len(disks))
@@ -193,13 +189,14 @@ func getStorageInfo(disks []StorageAPI) StorageInfo {
availableDataDisks = uint64(onlineDisks)
}
// Return calculated storage info, choose the lowest Total and
// Free as the total aggregated values. Total capacity is always
// the multiple of smallest disk among the disk list.
storageInfo := StorageInfo{
Total: validDisksInfo[0].Total * availableDataDisks,
Free: validDisksInfo[0].Free * availableDataDisks,
storageInfo := StorageInfo{}
// Combine all disks to get total usage.
var used uint64
for _, di := range validDisksInfo {
used = used + di.Used
}
storageInfo.Used = used
storageInfo.Backend.Type = Erasure
storageInfo.Backend.OnlineDisks = onlineDisks
+6 -37
View File
@@ -17,56 +17,25 @@
package cmd
import (
"context"
"os"
"reflect"
"testing"
"github.com/minio/minio/pkg/disk"
)
// TestStorageInfo - tests storage info.
func TestStorageInfo(t *testing.T) {
objLayer, fsDirs, err := prepareXL16()
if err != nil {
t.Fatalf("Unable to initialize 'XL' object layer.")
}
// Remove all dirs.
for _, dir := range fsDirs {
defer os.RemoveAll(dir)
}
// Get storage info first attempt.
disks16Info := objLayer.StorageInfo(context.Background())
// This test assumes homogenity between all disks,
// i.e if we loose one disk the effective storage
// usage values is assumed to decrease. If we have
// heterogenous environment this is not true all the time.
if disks16Info.Free <= 0 {
t.Fatalf("Diskinfo total free values should be greater 0")
}
if disks16Info.Total <= 0 {
t.Fatalf("Diskinfo total values should be greater 0")
}
}
// Sort valid disks info.
func TestSortingValidDisks(t *testing.T) {
testCases := []struct {
disksInfo []disk.Info
validDisksInfo []disk.Info
disksInfo []DiskInfo
validDisksInfo []DiskInfo
}{
// One of the disks is offline.
{
disksInfo: []disk.Info{
disksInfo: []DiskInfo{
{Total: 150, Free: 10},
{Total: 0, Free: 0},
{Total: 200, Free: 10},
{Total: 100, Free: 10},
},
validDisksInfo: []disk.Info{
validDisksInfo: []DiskInfo{
{Total: 100, Free: 10},
{Total: 150, Free: 10},
{Total: 200, Free: 10},
@@ -74,13 +43,13 @@ func TestSortingValidDisks(t *testing.T) {
},
// All disks are online.
{
disksInfo: []disk.Info{
disksInfo: []DiskInfo{
{Total: 150, Free: 10},
{Total: 200, Free: 10},
{Total: 100, Free: 10},
{Total: 115, Free: 10},
},
validDisksInfo: []disk.Info{
validDisksInfo: []DiskInfo{
{Total: 100, Free: 10},
{Total: 115, Free: 10},
{Total: 150, Free: 10},
-36
View File
@@ -1,36 +0,0 @@
## Minio Prometheus Metric
Minio server exposes an endpoint for Promethueus to scrape server data at `/minio/prometheus/metrics`.
### Prometheus probe
Prometheus is used to monitor Minio server information like http request, disk storage, network stats etc.. It uses a config file named `prometheus.yaml` to scrape data from server. The value for `metrics_path` and `targets` need to be configured in the config yaml to specify the endpoint and url as shown:
```
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: minio
metrics_path: /minio/prometheus/metrics
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9000']
```
Prometheus can be run by executing :
```
./prometheus --config.file=prometheus.yml
```
### List of Minio metric exposed
Minio exposes the following list of metric to Prometheus
- `minio_disk_storage_bytes` : Total byte count of disk storage available to current Minio server instance
- `minio_disk_storage_free_bytes` : Total byte count of free disk storage available to current Minio server instance
- `minio_http_requests_duration_seconds_bucket` : The bucket into which observations are counted for creating Histogram
- `minio_http_requests_duration_seconds_count` : The count of current number of observations i.e. total HTTP requests (HEAD/GET/PUT/POST/DELETE).
- `minio_http_requests_duration_seconds_sum` : The current aggregate time spent servicing all HTTP requests (HEAD/GET/PUT/POST/DELETE) in seconds
- `minio_http_requests_total` : Total number of requests served by current Minio server instance
- `minio_network_received_bytes_total` : Total number of bytes received by current Minio server instance
- `minio_network_sent_bytes_total` : Total number of bytes sent by current Minio server instance
- `minio_offline_disks` : Total number of offline disks for current Minio server instance
- `minio_total_disks` : Total number of disks for current Minio server instance
- `minio_server_start_time_seconds` : Time Unix time in seconds when current Minio server instance started
+20
View File
@@ -0,0 +1,20 @@
## Minio Monitoring Guide
Minio server exposes monitoring data over un-authenticated endpoints so monitoring tools can pick the data without you having to share Minio server credentials. This document lists the monitoring endpoints and relevant documentation.
### Healthcheck Probe
Minio server has two healthcheck related endpoints, a liveness probe to indicate if server is working fine and a readiness probe to indicate if server is not accepting connections due to heavy load.
- Liveness probe available at `/minio/health/live`
- Readiness probe available at `/minio/health/ready`
Read more on how to use these endpoints in [Minio healthcheck guide](https://github.com/minio/minio/blob/master/docs/metrics/healthcheck/README.md).
### Prometheus Probe
Minio server exposes Prometheus compatible data on a single endpoint.
- Prometheus data available at `/minio/prometheus/metrics`
To use this endpoint, setup Prometheus to scrape data from this endpoint. Read more on how to use Prometheues to monitor Minio server in [How to monitor Minio server with Prometheus](https://github.com/minio/cookbook/blob/master/docs/how-to-monitor-minio-with-prometheus.md).
@@ -4,11 +4,11 @@ Minio server exposes two un-authenticated, healthcheck endpoints - liveness prob
### Liveness probe
This probe is used to identify situations where the server is running but may not behave optimally, i.e. sluggish response or corrupt backend. Such problems can be *only* fixed by a restart.
This probe is used to identify situations where the server is running but may not behave optimally, i.e. sluggish response or corrupt back-end. Such problems can be *only* fixed by a restart.
Internally, Minio liveness probe handler does a ListBuckets call. If successful, the server returns 200 OK, otherwise 503 Service Unavailable.
When liveness probe fails, Kubernetes like platforms restart the container.
When liveness probe fails, Kubernetes like platforms restart the container.
### Readiness probe
@@ -5,7 +5,7 @@ version: '2'
# 9001 through 9004.
services:
minio1:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- data1:/data
ports:
@@ -15,7 +15,7 @@ services:
MINIO_SECRET_KEY: minio123
command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data
minio2:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- data2:/data
ports:
@@ -25,7 +25,7 @@ services:
MINIO_SECRET_KEY: minio123
command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data
minio3:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- data3:/data
ports:
@@ -35,7 +35,7 @@ services:
MINIO_SECRET_KEY: minio123
command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data
minio4:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- data4:/data
ports:
@@ -2,7 +2,7 @@ version: '3.1'
services:
minio1:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- minio1-data:/export
ports:
@@ -20,7 +20,7 @@ services:
- access_key
minio2:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- minio2-data:/export
ports:
@@ -38,7 +38,7 @@ services:
- access_key
minio3:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- minio3-data:/export
ports:
@@ -56,7 +56,7 @@ services:
- access_key
minio4:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- minio4-data:/export
ports:
@@ -2,7 +2,7 @@ version: '3'
services:
minio1:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- minio1-data:/export
ports:
@@ -20,7 +20,7 @@ services:
command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export
minio2:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- minio2-data:/export
ports:
@@ -38,7 +38,7 @@ services:
command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export
minio3:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- minio3-data:/export
ports:
@@ -56,7 +56,7 @@ services:
command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export
minio4:
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
volumes:
- minio4-data:/export
ports:
+3 -3
View File
@@ -124,7 +124,7 @@ spec:
- name: data
mountPath: "/data"
# Pulls the lastest Minio image from Docker Hub
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
args:
- server
- /data
@@ -303,7 +303,7 @@ spec:
value: "minio"
- name: MINIO_SECRET_KEY
value: "minio123"
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
args:
- server
- http://minio-0.minio.default.svc.cluster.local/data
@@ -514,7 +514,7 @@ spec:
containers:
- name: minio
# Pulls the default Minio image from Docker Hub
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
args:
- gateway
- gcs
@@ -21,7 +21,7 @@ spec:
value: "minio"
- name: MINIO_SECRET_KEY
value: "minio123"
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
args:
- server
- http://minio-0.minio.default.svc.cluster.local/data
@@ -21,7 +21,7 @@ spec:
containers:
- name: minio
# Pulls the default Minio image from Docker Hub
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
args:
- gateway
- gcs
@@ -29,7 +29,7 @@ spec:
- name: data
mountPath: "/data"
# Pulls the lastest Minio image from Docker Hub
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
args:
- server
- /data
+1 -1
View File
@@ -30,7 +30,7 @@ Above command deploys Minio on the Kubernetes cluster in the default configurati
| Parameter | Description | Default |
|----------------------------|-------------------------------------|---------------------------------------------------------|
| `image` | Minio image name | `minio/minio` |
| `imageTag` | Minio image tag. Possible values listed [here](https://hub.docker.com/r/minio/minio/tags/).| `RELEASE.2018-05-10T00-00-42Z`|
| `imageTag` | Minio image tag. Possible values listed [here](https://hub.docker.com/r/minio/minio/tags/).| `RELEASE.2018-05-16T23-35-33Z`|
| `imagePullPolicy` | Image pull policy | `Always` |
| `mode` | Minio server mode (`standalone`, `shared` or `distributed`)| `standalone` |
| `numberOfNodes` | Number of nodes (applicable only for Minio distributed mode). Should be 4 <= x <= 16 | `4` |
+1 -1
View File
@@ -54,7 +54,7 @@ spec:
value: "minio"
- name: MINIO_SECRET_KEY
value: "minio123"
image: minio/minio:RELEASE.2018-05-10T00-00-42Z
image: minio/minio:RELEASE.2018-05-16T23-35-33Z
imagePullPolicy: IfNotPresent
args: ["server", "http://minio-0.minio.default.svc.cluster.local/data", "http://minio-1.minio.default.svc.cluster.local/data", "http://minio-2.minio.default.svc.cluster.local/data", "http://minio-3.minio.default.svc.cluster.local/data"]
ports:
+10 -2
View File
@@ -70,8 +70,16 @@ openssl rsa -in private-pkcs8-key.key -aes256 -passout pass:PASSWORD -out privat
**Generate the self-signed certificate**:
Generate self-signed certificate using the below command (remember to replace `<domain.com>` with your actual domain name)
```sh
openssl req -new -x509 -days 3650 -key private.key -out public.crt -subj "/C=US/ST=state/L=location/O=organization/CN=domain"
openssl req -new -x509 -days 3650 -key private.key -out public.crt -subj "/C=US/ST=state/L=location/O=organization/CN=<domain.com>"
```
Generate self-signed wildcard certificate using the below command. This certificate will be valid for all the sub-domains under `domain.com`. Wildcard certificates come in handy while deploying distributed Minio instances where there may be multiple sub-domains under a single domain, with each one running a separate Minio instance.
```sh
openssl req -new -x509 -days 3650 -key private.key -out public.crt -subj "/C=US/ST=state/L=location/O=organization/CN=<*.domain.com>"
```
### Using OpenSSL (with IP address)
@@ -179,4 +187,4 @@ Minio can be configured to connect to other servers, whether Minio nodes or serv
* [TLS Configuration for Minio server on Kubernetes](https://github.com/minio/minio/tree/master/docs/tls/kubernetes)
* [Minio Client Complete Guide](https://docs.minio.io/docs/minio-client-complete-guide)
* [Generate Let's Encrypt Certificate](https://docs.minio.io/docs/generate-let-s-encypt-certificate-using-concert-for-minio)
* [Setup Nginx Proxy with Minio Server](https://docs.minio.io/docs/setup-nginx-proxy-with-minio)
* [Setup nginx Proxy with Minio Server](https://docs.minio.io/docs/setup-nginx-proxy-with-minio)
+14 -10
View File
@@ -10,6 +10,10 @@ This document explains how to configure Minio server with TLS certificates on Ku
- Acquire TLS certificates, either from a CA or [create self-signed certificates](https://docs.minio.io/docs/how-to-secure-access-to-minio-server-with-tls).
For a [distributed Minio setup](https://docs.minio.io/docs/distributed-minio-quickstart-guide), where there are multiple pods with different domain names expected to run, you will either need wildcard certificates valid for all the domains or have specific certificates for each domain. If you are going to use specific certificates, make sure to create Kubernetes secrets accordingly.
For testing purposes, here is [how to create self-signed certificates](https://github.com/minio/minio/tree/master/docs/tls#3-generate-self-signed-certificates).
## 2. Create Kubernetes secret
[Kubernetes secrets](https://kubernetes.io/docs/concepts/configuration/secret) are intended to hold sensitive information.
@@ -43,9 +47,9 @@ If you're using certificates provided by a CA, add the below section in your yam
secretName: tls-ssl-minio
items:
- key: public.crt
path: .minio/certs/public.crt
path: public.crt
- key: private.key
path: .minio/certs/private.key
path: private.key
```
In case you are using a self signed certificate, Minio server will not trust it by default. To add the certificate as a
@@ -58,11 +62,11 @@ trusted certificate, add the `public.crt` to the `.minio/certs/CAs` directory as
secretName: tls-ssl-minio
items:
- key: public.crt
path: .minio/certs/public.crt
path: public.crt
- key: private.key
path: .minio/certs/private.key
path: private.key
- key: public.crt
path: .minio/certs/CAs/public.crt
path: CAs/public.crt
```
Note that the `secretName` should be same as the secret name created in previous step. Then add the below section under
@@ -71,10 +75,10 @@ Note that the `secretName` should be same as the secret name created in previous
```yaml
volumeMounts:
- name: secret-volume
mountPath: /<user-running-minio>/
mountPath: /<user-running-minio>/.minio/certs
```
Here the name of `volumeMount` should match the name of `volume` created previously. Also `mountPath` is the path of
Minio server's config directory, (used to store the certificates). By default the location is
`/user-running-minio/.minio/certs`. Update the `mountPath` to appropriate parent directory for Minio server config
directory. (Tip: In default Kubernetes configuration this will be `/root`).
Here the name of `volumeMount` should match the name of `volume` created previously. Also `mountPath` must be set to the path of
the Minio server's config sub-directory that is used to store certificates. By default, the location is
`/user-running-minio/.minio/certs`. Tip: In a standard Kubernetes configuration, this will be `/root/.minio/certs`.
Kubernetes will mount the secrets volume read-only, so avoid setting `mountPath` to a path that Minio server expects to write to.
+3
View File
@@ -28,4 +28,7 @@ type Info struct {
Files uint64
Ffree uint64
FSType string
// Usage is calculated per tenant.
Usage uint64
}
+4 -2
View File
@@ -61,11 +61,13 @@ func NewReader(src io.Reader, size int64, md5Hex, sha256Hex string) (*Reader, er
if len(sha256sum) != 0 {
sha256Hash = sha256.New()
}
if size >= 0 {
src = io.LimitReader(src, size)
}
return &Reader{
md5sum: md5sum,
sha256sum: sha256sum,
src: io.LimitReader(src, size),
src: src,
size: size,
md5Hash: md5.New(),
sha256Hash: sha256Hash,
+1 -1
View File
@@ -5,7 +5,7 @@ This quickstart guide will show you how to install the Minio Admin client SDK, c
This document assumes that you have a working [Golang setup](https://docs.minio.io/docs/how-to-install-golang).
## Download from Github
## Download from GitHub
```sh
+44
View File
@@ -0,0 +1,44 @@
// +build ignore
/*
* Minio Cloud Storage, (C) 2018 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package main
import (
"log"
"github.com/minio/minio/pkg/madmin"
)
func main() {
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
// dummy values, please replace them with original values.
// API requests are secure (HTTPS) if secure=true and insecure (HTTPS) otherwise.
// New returns an Minio Admin client object.
madmClnt, err := madmin.New("your-minio.example.com:9000", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
if err != nil {
log.Fatalln(err)
}
st, err := madmClnt.ServerInfo()
if err != nil {
log.Fatalln(err)
}
log.Println(st)
}
+2 -4
View File
@@ -44,10 +44,8 @@ type DriveInfo HealDriveInfo
// StorageInfo - represents total capacity of underlying storage.
type StorageInfo struct {
// Total disk space.
Total int64
// Free available disk space.
Free int64
Used uint64 // Total used spaced per tenant.
// Backend type.
Backend struct {
// Represents various backend types, currently on FS and Erasure.
+12 -12
View File
@@ -29,26 +29,26 @@ const ResourceARNPrefix = "arn:aws:s3:::"
// Resource - resource in policy statement.
type Resource struct {
bucketName string
pattern string
BucketName string
Pattern string
}
func (r Resource) isBucketPattern() bool {
return !strings.Contains(r.pattern, "/")
return !strings.Contains(r.Pattern, "/")
}
func (r Resource) isObjectPattern() bool {
return strings.Contains(r.pattern, "/") || strings.Contains(r.bucketName, "*")
return strings.Contains(r.Pattern, "/") || strings.Contains(r.BucketName, "*")
}
// IsValid - checks whether Resource is valid or not.
func (r Resource) IsValid() bool {
return r.bucketName != "" && r.pattern != ""
return r.BucketName != "" && r.Pattern != ""
}
// Match - matches object name with resource pattern.
func (r Resource) Match(resource string) bool {
return wildcard.Match(r.pattern, resource)
return wildcard.Match(r.Pattern, resource)
}
// MarshalJSON - encodes Resource to JSON data.
@@ -61,7 +61,7 @@ func (r Resource) MarshalJSON() ([]byte, error) {
}
func (r Resource) String() string {
return ResourceARNPrefix + r.pattern
return ResourceARNPrefix + r.Pattern
}
// UnmarshalJSON - decodes JSON data to Resource.
@@ -87,7 +87,7 @@ func (r Resource) Validate(bucketName string) error {
return fmt.Errorf("invalid resource")
}
if !wildcard.Match(r.bucketName, bucketName) {
if !wildcard.Match(r.BucketName, bucketName) {
return fmt.Errorf("bucket name does not match")
}
@@ -108,8 +108,8 @@ func parseResource(s string) (Resource, error) {
}
return Resource{
bucketName: bucketName,
pattern: pattern,
BucketName: bucketName,
Pattern: pattern,
}, nil
}
@@ -125,7 +125,7 @@ func NewResource(bucketName, keyName string) Resource {
}
return Resource{
bucketName: bucketName,
pattern: pattern,
BucketName: bucketName,
Pattern: pattern,
}
}