mirror of
https://github.com/minio/mc.git
synced 2025-11-10 13:42:32 +03:00
Add admin lock command (#1942)
This commit is contained in:
committed by
Harshavardhana
parent
86777e7863
commit
7cec8f2285
157
cmd/admin-lock-clear.go
Normal file
157
cmd/admin-lock-clear.go
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Minio Client (C) 2016 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/minio/cli"
|
||||||
|
"github.com/minio/minio/pkg/madmin"
|
||||||
|
"github.com/minio/minio/pkg/probe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
adminLockClearFlags = []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "older-than, o",
|
||||||
|
Usage: "Only show locks that are older than a specified time, i.e. 30s",
|
||||||
|
Value: "0s",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var adminLockClearCmd = cli.Command{
|
||||||
|
Name: "clear",
|
||||||
|
Usage: "Clear locks hold in a given Minio server",
|
||||||
|
Action: mainAdminLockClear,
|
||||||
|
Flags: append(adminLockClearFlags, globalFlags...),
|
||||||
|
CustomHelpTemplate: `NAME:
|
||||||
|
mc admin lock {{.Name}} - {{.Usage}}
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
mc admin lock {{.Name}} ALIAS/BUCKET/PREFIX
|
||||||
|
|
||||||
|
FLAGS:
|
||||||
|
{{range .Flags}}{{.}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
EXAMPLES:
|
||||||
|
1. Clear all locks hold by 'testbucket' in a Minio server represented by its alias 'play'.
|
||||||
|
$ mc admin lock {{.Name}} play/testbucket
|
||||||
|
|
||||||
|
2. Clear all 'testbucket' locks that are older than 15 minutes.
|
||||||
|
$ mc admin lock {{.Name}} --older-than 15m play/testbucket/
|
||||||
|
|
||||||
|
3. Clear all locks hold by all objects under 'dir' prefix
|
||||||
|
$ mc admin lock {{.Name}} play/testbucket/dir/
|
||||||
|
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
// lockClearMessage container to hold locks information.
|
||||||
|
type lockClearMessage struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
LockInfo madmin.VolumeLockInfo `json:"volumeLockInfo"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// String colorized service status message.
|
||||||
|
func (u lockClearMessage) String() string {
|
||||||
|
msg := fmt.Sprintf("%s/%s (LocksOnObject: %d, locksAcquiredOnObject: %d, totalBlockLocks:%d): ",
|
||||||
|
u.LockInfo.Bucket,
|
||||||
|
u.LockInfo.Object,
|
||||||
|
u.LockInfo.LocksOnObject,
|
||||||
|
u.LockInfo.LocksAcquiredOnObject,
|
||||||
|
u.LockInfo.TotalBlockedLocks)
|
||||||
|
for _, detail := range u.LockInfo.LockDetailsOnObject {
|
||||||
|
msg += fmt.Sprintf(" %+v", detail)
|
||||||
|
}
|
||||||
|
msg += "\n"
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON jsonified service status Message message.
|
||||||
|
func (u lockClearMessage) JSON() string {
|
||||||
|
u.Status = "success"
|
||||||
|
statusJSONBytes, e := json.Marshal(u)
|
||||||
|
fatalIf(probe.NewError(e), "Unable to marshal into JSON.")
|
||||||
|
|
||||||
|
return string(statusJSONBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkAdminLockClearSyntax - validate all the passed arguments
|
||||||
|
func checkAdminLockClearSyntax(ctx *cli.Context) {
|
||||||
|
if len(ctx.Args()) == 0 || len(ctx.Args()) > 2 {
|
||||||
|
cli.ShowCommandHelpAndExit(ctx, "clear", 1) // last argument is exit code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mainAdminLockClear(ctx *cli.Context) error {
|
||||||
|
|
||||||
|
setGlobalsFromContext(ctx)
|
||||||
|
checkAdminLockClearSyntax(ctx)
|
||||||
|
|
||||||
|
// Get the alias parameter from cli
|
||||||
|
args := ctx.Args()
|
||||||
|
aliasedURL := args.Get(0)
|
||||||
|
|
||||||
|
// Parse older-than flag
|
||||||
|
olderThan, e := time.ParseDuration(ctx.String("older-than"))
|
||||||
|
fatalIf(probe.NewError(e), "Unable to parse the passed older-than flag.")
|
||||||
|
|
||||||
|
// Fetch the server's address stored in config
|
||||||
|
_, _, hostCfg, err := expandAlias(aliasedURL)
|
||||||
|
if err != nil {
|
||||||
|
return err.ToGoError()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if alias exists
|
||||||
|
if hostCfg == nil {
|
||||||
|
fatalIf(errInvalidAliasedURL(aliasedURL).Trace(aliasedURL), "The specified alias is not found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the server address
|
||||||
|
url, e := url.Parse(hostCfg.URL)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
isSSL := (url.Scheme == "https")
|
||||||
|
|
||||||
|
// Create a new Minio Admin Client
|
||||||
|
client, e := madmin.New(url.Host, hostCfg.AccessKey, hostCfg.SecretKey, isSSL)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
aliasedURL = filepath.ToSlash(aliasedURL)
|
||||||
|
|
||||||
|
splits := splitStr(aliasedURL, "/", 3)
|
||||||
|
|
||||||
|
// Clear locks related to a specified pair of bucket and prefix
|
||||||
|
locksInfo, e := client.ClearLocks(splits[1], splits[2], olderThan)
|
||||||
|
fatalIf(probe.NewError(e), "Cannot clear the specified locks.")
|
||||||
|
|
||||||
|
for _, l := range locksInfo {
|
||||||
|
printMsg(lockClearMessage{LockInfo: l})
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
157
cmd/admin-lock-list.go
Normal file
157
cmd/admin-lock-list.go
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Minio Client (C) 2016 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/minio/cli"
|
||||||
|
"github.com/minio/minio/pkg/madmin"
|
||||||
|
"github.com/minio/minio/pkg/probe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
adminLockListFlags = []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "older-than, o",
|
||||||
|
Usage: "Only show locks that are older than a specified time, i.e. 30s",
|
||||||
|
Value: "0s",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var adminLockListCmd = cli.Command{
|
||||||
|
Name: "list",
|
||||||
|
Usage: "Get the list of locks hold in a given Minio server",
|
||||||
|
Action: mainAdminLockList,
|
||||||
|
Flags: append(adminLockListFlags, globalFlags...),
|
||||||
|
CustomHelpTemplate: `NAME:
|
||||||
|
mc admin lock {{.Name}} - {{.Usage}}
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
mc admin lock {{.Name}} ALIAS/BUCKET/PREFIX
|
||||||
|
|
||||||
|
FLAGS:
|
||||||
|
{{range .Flags}}{{.}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
EXAMPLES:
|
||||||
|
1. List hold locks related to testbucket in a Minio server represented by its alias 'play'.
|
||||||
|
$ mc admin lock {{.Name}} play/testbucket/
|
||||||
|
|
||||||
|
2. List locks that are hold for more than 15 minutes.
|
||||||
|
$ mc admin lock {{.Name}} --older-than 15m play/testbucket/
|
||||||
|
|
||||||
|
3. List locks hold by all objects under dir prefix
|
||||||
|
$ mc admin lock {{.Name}} play/testbucket/dir/
|
||||||
|
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
// lockListMessage container to hold locks information.
|
||||||
|
type lockListMessage struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
LockInfo madmin.VolumeLockInfo `json:"volumeLockInfo"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// String colorized service status message.
|
||||||
|
func (u lockListMessage) String() string {
|
||||||
|
msg := fmt.Sprintf("%s/%s (LocksOnObject: %d, locksAcquiredOnObject: %d, totalBlockLocks:%d): ",
|
||||||
|
u.LockInfo.Bucket,
|
||||||
|
u.LockInfo.Object,
|
||||||
|
u.LockInfo.LocksOnObject,
|
||||||
|
u.LockInfo.LocksAcquiredOnObject,
|
||||||
|
u.LockInfo.TotalBlockedLocks)
|
||||||
|
for _, detail := range u.LockInfo.LockDetailsOnObject {
|
||||||
|
msg += fmt.Sprintf(" %+v", detail)
|
||||||
|
}
|
||||||
|
msg += "\n"
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON jsonified service status Message message.
|
||||||
|
func (u lockListMessage) JSON() string {
|
||||||
|
u.Status = "success"
|
||||||
|
statusJSONBytes, e := json.Marshal(u)
|
||||||
|
fatalIf(probe.NewError(e), "Unable to marshal into JSON.")
|
||||||
|
|
||||||
|
return string(statusJSONBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkAdminLockListSyntax - validate all the passed arguments
|
||||||
|
func checkAdminLockListSyntax(ctx *cli.Context) {
|
||||||
|
if len(ctx.Args()) == 0 || len(ctx.Args()) > 2 {
|
||||||
|
cli.ShowCommandHelpAndExit(ctx, "list", 1) // last argument is exit code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mainAdminLockList(ctx *cli.Context) error {
|
||||||
|
|
||||||
|
setGlobalsFromContext(ctx)
|
||||||
|
checkAdminLockListSyntax(ctx)
|
||||||
|
|
||||||
|
// Get the alias parameter from cli
|
||||||
|
args := ctx.Args()
|
||||||
|
aliasedURL := args.Get(0)
|
||||||
|
|
||||||
|
// Parse older-than flag
|
||||||
|
olderThan, e := time.ParseDuration(ctx.String("older-than"))
|
||||||
|
fatalIf(probe.NewError(e), "Unable to parse the passed older-than flag.")
|
||||||
|
|
||||||
|
// Fetch the server's address stored in config
|
||||||
|
_, _, hostCfg, err := expandAlias(aliasedURL)
|
||||||
|
if err != nil {
|
||||||
|
return err.ToGoError()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if alias exists
|
||||||
|
if hostCfg == nil {
|
||||||
|
fatalIf(errInvalidAliasedURL(aliasedURL).Trace(aliasedURL), "The specified alias is not found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the server address
|
||||||
|
url, e := url.Parse(hostCfg.URL)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
isSSL := (url.Scheme == "https")
|
||||||
|
|
||||||
|
// Create a new Minio Admin Client
|
||||||
|
client, e := madmin.New(url.Host, hostCfg.AccessKey, hostCfg.SecretKey, isSSL)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
aliasedURL = filepath.ToSlash(aliasedURL)
|
||||||
|
|
||||||
|
splits := splitStr(aliasedURL, "/", 3)
|
||||||
|
|
||||||
|
// Fetch the lock info related to a specified pair of bucket and prefix
|
||||||
|
locksInfo, e := client.ListLocks(splits[1], splits[2], olderThan)
|
||||||
|
fatalIf(probe.NewError(e), "Cannot get lock status.")
|
||||||
|
|
||||||
|
for _, l := range locksInfo {
|
||||||
|
printMsg(lockListMessage{LockInfo: l})
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
63
cmd/admin-lock.go
Normal file
63
cmd/admin-lock.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Minio Client (C) 2016 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 "github.com/minio/cli"
|
||||||
|
|
||||||
|
var (
|
||||||
|
adminLockFlags = []cli.Flag{}
|
||||||
|
)
|
||||||
|
|
||||||
|
var adminLockCmd = cli.Command{
|
||||||
|
Name: "lock",
|
||||||
|
Usage: "Control locks in servers.",
|
||||||
|
Action: mainAdminLock,
|
||||||
|
Flags: append(adminLockFlags, globalFlags...),
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
adminLockListCmd,
|
||||||
|
adminLockClearCmd,
|
||||||
|
},
|
||||||
|
CustomHelpTemplate: `NAME:
|
||||||
|
{{.Name}} - {{.Usage}}
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
{{.Name}} [FLAGS] COMMAND
|
||||||
|
|
||||||
|
FLAGS:
|
||||||
|
{{range .Flags}}{{.}}
|
||||||
|
{{end}}
|
||||||
|
COMMANDS:
|
||||||
|
{{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
|
||||||
|
{{end}}
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
// mainAdminLock is the handle for "mc admin lock" command.
|
||||||
|
func mainAdminLock(ctx *cli.Context) error {
|
||||||
|
// Set global flags from context.
|
||||||
|
setGlobalsFromContext(ctx)
|
||||||
|
|
||||||
|
if ctx.Args().First() != "" { // command help.
|
||||||
|
cli.ShowCommandHelp(ctx, ctx.Args().First())
|
||||||
|
} else {
|
||||||
|
// command with Subcommands is an App.
|
||||||
|
cli.ShowAppHelp(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
// Sub-commands like "list", "unlock" have their own main.
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ var adminCmd = cli.Command{
|
|||||||
Flags: append(adminFlags, globalFlags...),
|
Flags: append(adminFlags, globalFlags...),
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
adminServiceCmd,
|
adminServiceCmd,
|
||||||
|
adminLockCmd,
|
||||||
},
|
},
|
||||||
CustomHelpTemplate: `NAME:
|
CustomHelpTemplate: `NAME:
|
||||||
{{.Name}} - {{.Usage}}
|
{{.Name}} - {{.Usage}}
|
||||||
|
|||||||
@@ -920,19 +920,8 @@ func (c *s3Client) url2BucketAndObject() (bucketName, objectName string) {
|
|||||||
path = string(c.targetURL.Separator) + bucket + c.targetURL.Path
|
path = string(c.targetURL.Separator) + bucket + c.targetURL.Path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
splits := strings.SplitN(path, string(c.targetURL.Separator), 3)
|
tokens := splitStr(path, string(c.targetURL.Separator), 3)
|
||||||
switch len(splits) {
|
return tokens[1], tokens[2]
|
||||||
case 0, 1:
|
|
||||||
bucketName = ""
|
|
||||||
objectName = ""
|
|
||||||
case 2:
|
|
||||||
bucketName = splits[1]
|
|
||||||
objectName = ""
|
|
||||||
case 3:
|
|
||||||
bucketName = splits[1]
|
|
||||||
objectName = splits[2]
|
|
||||||
}
|
|
||||||
return bucketName, objectName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// splitPath split path into bucket and object.
|
// splitPath split path into bucket and object.
|
||||||
@@ -955,13 +944,8 @@ func (c *s3Client) splitPath(path string) (bucketName, objectName string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens := strings.SplitN(path, string(c.targetURL.Separator), 2)
|
tokens := splitStr(path, string(c.targetURL.Separator), 2)
|
||||||
bucketName = tokens[0]
|
return tokens[0], tokens[1]
|
||||||
if len(tokens) == 2 {
|
|
||||||
objectName = tokens[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return bucketName, objectName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bucket API operations.
|
/// Bucket API operations.
|
||||||
|
|||||||
12
cmd/utils.go
12
cmd/utils.go
@@ -21,6 +21,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/minio/mc/pkg/console"
|
"github.com/minio/mc/pkg/console"
|
||||||
@@ -75,3 +76,14 @@ func dumpTLSCertificates(t *tls.ConnectionState) {
|
|||||||
func isStdIO(reader io.Reader) bool {
|
func isStdIO(reader io.Reader) bool {
|
||||||
return reader == os.Stdin || reader == os.Stdout || reader == os.Stderr
|
return reader == os.Stdin || reader == os.Stdout || reader == os.Stderr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// splitStr splits a string into n parts, empty strings are added
|
||||||
|
// if we are not able to reach n elements
|
||||||
|
func splitStr(path, sep string, n int) []string {
|
||||||
|
splits := strings.SplitN(path, sep, n)
|
||||||
|
// Add empty strings if we found elements less than nr
|
||||||
|
for i := n - len(splits); i > 0; i-- {
|
||||||
|
splits = append(splits, "")
|
||||||
|
}
|
||||||
|
return splits
|
||||||
|
}
|
||||||
|
|||||||
47
vendor/github.com/minio/minio/pkg/madmin/examples/lock-clear.go
generated
vendored
Normal file
47
vendor/github.com/minio/minio/pkg/madmin/examples/lock-clear.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minio Cloud Storage, (C) 2016 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"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/minio/minio/pkg/madmin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear locks held on mybucket/myprefix older than olderThan seconds.
|
||||||
|
olderThan := time.Duration(30 * time.Second)
|
||||||
|
locksCleared, err := madmClnt.ClearLocks("mybucket", "myprefix", olderThan)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
log.Println(locksCleared)
|
||||||
|
}
|
||||||
46
vendor/github.com/minio/minio/pkg/madmin/examples/lock-list.go
generated
vendored
Normal file
46
vendor/github.com/minio/minio/pkg/madmin/examples/lock-list.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minio Cloud Storage, (C) 2016 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"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/minio/minio/pkg/madmin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List locks held on mybucket/myprefix older than 30s.
|
||||||
|
locksHeld, err := madmClnt.ListLocks("mybucket", "myprefix", time.Duration(30*time.Second))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
log.Println(locksHeld)
|
||||||
|
}
|
||||||
44
vendor/github.com/minio/minio/pkg/madmin/examples/service-restart.go
generated
vendored
Normal file
44
vendor/github.com/minio/minio/pkg/madmin/examples/service-restart.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minio Cloud Storage, (C) 2016 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 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = madmClnt.ServiceRestart()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
log.Println("Success")
|
||||||
|
}
|
||||||
44
vendor/github.com/minio/minio/pkg/madmin/examples/service-status.go
generated
vendored
Normal file
44
vendor/github.com/minio/minio/pkg/madmin/examples/service-status.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minio Cloud Storage, (C) 2016 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.ServiceStatus()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
log.Println(st)
|
||||||
|
}
|
||||||
44
vendor/github.com/minio/minio/pkg/madmin/examples/service-stop.go
generated
vendored
Normal file
44
vendor/github.com/minio/minio/pkg/madmin/examples/service-stop.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minio Cloud Storage, (C) 2016 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = madmClnt.ServiceStop()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
log.Println("Success")
|
||||||
|
}
|
||||||
151
vendor/github.com/minio/minio/pkg/madmin/lock-commands.go
generated
vendored
Normal file
151
vendor/github.com/minio/minio/pkg/madmin/lock-commands.go
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* Minio Cloud Storage, (C) 2016 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 madmin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type statusType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
runningStatus statusType = "Running"
|
||||||
|
blockedStatus statusType = "Blocked"
|
||||||
|
)
|
||||||
|
|
||||||
|
type lockType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
debugRLockStr lockType = "RLock"
|
||||||
|
debugWLockStr lockType = "WLock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OpsLockState - represents lock specific details.
|
||||||
|
type OpsLockState struct {
|
||||||
|
OperationID string `json:"opsID"` // String containing operation ID.
|
||||||
|
LockSource string `json:"lockSource"` // Operation type (GetObject, PutObject...)
|
||||||
|
LockType lockType `json:"lockType"` // Lock type (RLock, WLock)
|
||||||
|
Status statusType `json:"status"` // Status can be Running/Ready/Blocked.
|
||||||
|
Since time.Time `json:"statusSince"` // Time when the lock was initially held.
|
||||||
|
Duration time.Duration `json:"statusDuration"` // Duration since the lock was held.
|
||||||
|
}
|
||||||
|
|
||||||
|
// VolumeLockInfo - represents summary and individual lock details of all
|
||||||
|
// locks held on a given bucket, object.
|
||||||
|
type VolumeLockInfo struct {
|
||||||
|
Bucket string `json:"bucket"`
|
||||||
|
Object string `json:"object"`
|
||||||
|
// All locks blocked + running for given <volume,path> pair.
|
||||||
|
LocksOnObject int64 `json:"locksOnObject"`
|
||||||
|
// Count of operations which has successfully acquired the lock
|
||||||
|
// but hasn't unlocked yet( operation in progress).
|
||||||
|
LocksAcquiredOnObject int64 `json:"locksAcquiredOnObject"`
|
||||||
|
// Count of operations which are blocked waiting for the lock
|
||||||
|
// to be released.
|
||||||
|
TotalBlockedLocks int64 `json:"locksBlockedOnObject"`
|
||||||
|
// State information containing state of the locks for all operations
|
||||||
|
// on given <volume,path> pair.
|
||||||
|
LockDetailsOnObject []OpsLockState `json:"lockDetailsOnObject"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// getLockInfos - unmarshal []VolumeLockInfo from a reader.
|
||||||
|
func getLockInfos(body io.Reader) ([]VolumeLockInfo, error) {
|
||||||
|
respBytes, err := ioutil.ReadAll(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var lockInfos []VolumeLockInfo
|
||||||
|
|
||||||
|
err = json.Unmarshal(respBytes, &lockInfos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return lockInfos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListLocks - Calls List Locks Management API to fetch locks matching
|
||||||
|
// bucket, prefix and held before the duration supplied.
|
||||||
|
func (adm *AdminClient) ListLocks(bucket, prefix string, olderThan time.Duration) ([]VolumeLockInfo, error) {
|
||||||
|
queryVal := make(url.Values)
|
||||||
|
queryVal.Set("lock", "")
|
||||||
|
queryVal.Set("bucket", bucket)
|
||||||
|
queryVal.Set("prefix", prefix)
|
||||||
|
queryVal.Set("older-than", olderThan.String())
|
||||||
|
|
||||||
|
hdrs := make(http.Header)
|
||||||
|
hdrs.Set(minioAdminOpHeader, "list")
|
||||||
|
|
||||||
|
reqData := requestData{
|
||||||
|
queryValues: queryVal,
|
||||||
|
customHeaders: hdrs,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute GET on /?lock to list locks.
|
||||||
|
resp, err := adm.executeMethod("GET", reqData)
|
||||||
|
|
||||||
|
defer closeResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New("Got HTTP Status: " + resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return getLockInfos(resp.Body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearLocks - Calls Clear Locks Management API to clear locks held
|
||||||
|
// on bucket, matching prefix older than duration supplied.
|
||||||
|
func (adm *AdminClient) ClearLocks(bucket, prefix string, olderThan time.Duration) ([]VolumeLockInfo, error) {
|
||||||
|
queryVal := make(url.Values)
|
||||||
|
queryVal.Set("lock", "")
|
||||||
|
queryVal.Set("bucket", bucket)
|
||||||
|
queryVal.Set("prefix", prefix)
|
||||||
|
queryVal.Set("older-than", olderThan.String())
|
||||||
|
|
||||||
|
hdrs := make(http.Header)
|
||||||
|
hdrs.Set(minioAdminOpHeader, "clear")
|
||||||
|
|
||||||
|
reqData := requestData{
|
||||||
|
queryValues: queryVal,
|
||||||
|
customHeaders: hdrs,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute POST on /?lock to clear locks.
|
||||||
|
resp, err := adm.executeMethod("POST", reqData)
|
||||||
|
|
||||||
|
defer closeResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New("Got HTTP Status: " + resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return getLockInfos(resp.Body)
|
||||||
|
}
|
||||||
6
vendor/github.com/minio/minio/pkg/madmin/service.go
generated
vendored
6
vendor/github.com/minio/minio/pkg/madmin/service.go
generated
vendored
@@ -77,7 +77,7 @@ func (adm *AdminClient) ServiceStatus() (ServiceStatusMetadata, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return ServiceStatusMetadata{}, errors.New("Got " + resp.Status)
|
return ServiceStatusMetadata{}, errors.New("Got HTTP Status: " + resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
respBytes, err := ioutil.ReadAll(resp.Body)
|
respBytes, err := ioutil.ReadAll(resp.Body)
|
||||||
@@ -113,7 +113,7 @@ func (adm *AdminClient) ServiceStop() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return errors.New("Got " + resp.Status)
|
return errors.New("Got HTTP Status: " + resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -137,7 +137,7 @@ func (adm *AdminClient) ServiceRestart() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return errors.New("Got " + resp.Status)
|
return errors.New("Got HTTP Status: " + resp.Status)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@@ -80,10 +80,10 @@
|
|||||||
"revisionTime": "2016-08-18T00:31:20Z"
|
"revisionTime": "2016-08-18T00:31:20Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "ObCt0PoF41PGfeNCcJS6McmiFNs=",
|
"checksumSHA1": "5+Z11r2dweplJF0rTgmn1gtCsjw=",
|
||||||
"path": "github.com/minio/minio/pkg/madmin",
|
"path": "github.com/minio/minio/pkg/madmin",
|
||||||
"revision": "f57f773189ec9eda37dbf5ffd8eb0372cf0a4b39",
|
"revision": "c8f57133a4384ea98206560b691f50e7520007b9",
|
||||||
"revisionTime": "2016-12-21T02:49:48Z"
|
"revisionTime": "2017-01-04T07:39:22Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "github.com/minio/minio/pkg/probe",
|
"path": "github.com/minio/minio/pkg/probe",
|
||||||
|
|||||||
Reference in New Issue
Block a user