mirror of
				https://github.com/minio/minio.git
				synced 2025-11-04 10:11:09 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			198 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
 * 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 cmd
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"net/http"
 | 
						|
	"net/url"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	minioAdminOpHeader = "X-Minio-Operation"
 | 
						|
)
 | 
						|
 | 
						|
// ServiceStatusHandler - GET /?service
 | 
						|
// HTTP header x-minio-operation: status
 | 
						|
// ----------
 | 
						|
// Fetches server status information like total disk space available
 | 
						|
// to use, online disks, offline disks and quorum threshold.
 | 
						|
func (adminAPI adminAPIHandlers) ServiceStatusHandler(w http.ResponseWriter, r *http.Request) {
 | 
						|
	adminAPIErr := checkRequestAuthType(r, "", "", "")
 | 
						|
	if adminAPIErr != ErrNone {
 | 
						|
		writeErrorResponse(w, adminAPIErr, r.URL)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	storageInfo := newObjectLayerFn().StorageInfo()
 | 
						|
	jsonBytes, err := json.Marshal(storageInfo)
 | 
						|
	if err != nil {
 | 
						|
		writeErrorResponse(w, ErrInternalError, r.URL)
 | 
						|
		errorIf(err, "Failed to marshal storage info into json.")
 | 
						|
		return
 | 
						|
	}
 | 
						|
	// Reply with storage information (across nodes in a
 | 
						|
	// distributed setup) as json.
 | 
						|
	writeSuccessResponseJSON(w, jsonBytes)
 | 
						|
}
 | 
						|
 | 
						|
// ServiceRestartHandler - POST /?service
 | 
						|
// HTTP header x-minio-operation: restart
 | 
						|
// ----------
 | 
						|
// Restarts minio server gracefully. In a distributed setup,  restarts
 | 
						|
// all the servers in the cluster.
 | 
						|
func (adminAPI adminAPIHandlers) ServiceRestartHandler(w http.ResponseWriter, r *http.Request) {
 | 
						|
	adminAPIErr := checkRequestAuthType(r, "", "", "")
 | 
						|
	if adminAPIErr != ErrNone {
 | 
						|
		writeErrorResponse(w, adminAPIErr, r.URL)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Reply to the client before restarting minio server.
 | 
						|
	w.WriteHeader(http.StatusOK)
 | 
						|
 | 
						|
	sendServiceCmd(globalAdminPeers, serviceRestart)
 | 
						|
}
 | 
						|
 | 
						|
// Type-safe lock query params.
 | 
						|
type lockQueryKey string
 | 
						|
 | 
						|
// Only valid query params for list/clear locks management APIs.
 | 
						|
const (
 | 
						|
	lockBucket    lockQueryKey = "bucket"
 | 
						|
	lockPrefix    lockQueryKey = "prefix"
 | 
						|
	lockOlderThan lockQueryKey = "older-than"
 | 
						|
)
 | 
						|
 | 
						|
// validateLockQueryParams - Validates query params for list/clear locks management APIs.
 | 
						|
func validateLockQueryParams(vars url.Values) (string, string, time.Duration, APIErrorCode) {
 | 
						|
	bucket := vars.Get(string(lockBucket))
 | 
						|
	prefix := vars.Get(string(lockPrefix))
 | 
						|
	relTimeStr := vars.Get(string(lockOlderThan))
 | 
						|
 | 
						|
	// N B empty bucket name is invalid
 | 
						|
	if !IsValidBucketName(bucket) {
 | 
						|
		return "", "", time.Duration(0), ErrInvalidBucketName
 | 
						|
	}
 | 
						|
 | 
						|
	// empty prefix is valid.
 | 
						|
	if !IsValidObjectPrefix(prefix) {
 | 
						|
		return "", "", time.Duration(0), ErrInvalidObjectName
 | 
						|
	}
 | 
						|
 | 
						|
	// If older-than parameter was empty then set it to 0s to list
 | 
						|
	// all locks older than now.
 | 
						|
	if relTimeStr == "" {
 | 
						|
		relTimeStr = "0s"
 | 
						|
	}
 | 
						|
	relTime, err := time.ParseDuration(relTimeStr)
 | 
						|
	if err != nil {
 | 
						|
		errorIf(err, "Failed to parse duration passed as query value.")
 | 
						|
		return "", "", time.Duration(0), ErrInvalidDuration
 | 
						|
	}
 | 
						|
 | 
						|
	return bucket, prefix, relTime, ErrNone
 | 
						|
}
 | 
						|
 | 
						|
// ListLocksHandler - GET /?lock&bucket=mybucket&prefix=myprefix&older-than=rel_time
 | 
						|
// - bucket is a mandatory query parameter
 | 
						|
// - prefix and older-than are optional query parameters
 | 
						|
// HTTP header x-minio-operation: list
 | 
						|
// ---------
 | 
						|
// Lists locks held on a given bucket, prefix and relative time.
 | 
						|
func (adminAPI adminAPIHandlers) ListLocksHandler(w http.ResponseWriter, r *http.Request) {
 | 
						|
	adminAPIErr := checkRequestAuthType(r, "", "", "")
 | 
						|
	if adminAPIErr != ErrNone {
 | 
						|
		writeErrorResponse(w, adminAPIErr, r.URL)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	vars := r.URL.Query()
 | 
						|
	bucket, prefix, relTime, adminAPIErr := validateLockQueryParams(vars)
 | 
						|
	if adminAPIErr != ErrNone {
 | 
						|
		writeErrorResponse(w, adminAPIErr, r.URL)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Fetch lock information of locks matching bucket/prefix that
 | 
						|
	// are available since relTime.
 | 
						|
	volLocks, err := listPeerLocksInfo(globalAdminPeers, bucket, prefix, relTime)
 | 
						|
	if err != nil {
 | 
						|
		writeErrorResponse(w, ErrInternalError, r.URL)
 | 
						|
		errorIf(err, "Failed to fetch lock information from remote nodes.")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Marshal list of locks as json.
 | 
						|
	jsonBytes, err := json.Marshal(volLocks)
 | 
						|
	if err != nil {
 | 
						|
		writeErrorResponse(w, ErrInternalError, r.URL)
 | 
						|
		errorIf(err, "Failed to marshal lock information into json.")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Reply with list of locks held on bucket, matching prefix
 | 
						|
	// older than relTime supplied, as json.
 | 
						|
	writeSuccessResponseJSON(w, jsonBytes)
 | 
						|
}
 | 
						|
 | 
						|
// ClearLocksHandler - POST /?lock&bucket=mybucket&prefix=myprefix&older-than=relTime
 | 
						|
// - bucket is a mandatory query parameter
 | 
						|
// - prefix and older-than are optional query parameters
 | 
						|
// HTTP header x-minio-operation: clear
 | 
						|
// ---------
 | 
						|
// Clear locks held on a given bucket, prefix and relative time.
 | 
						|
func (adminAPI adminAPIHandlers) ClearLocksHandler(w http.ResponseWriter, r *http.Request) {
 | 
						|
	adminAPIErr := checkRequestAuthType(r, "", "", "")
 | 
						|
	if adminAPIErr != ErrNone {
 | 
						|
		writeErrorResponse(w, adminAPIErr, r.URL)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	vars := r.URL.Query()
 | 
						|
	bucket, prefix, relTime, adminAPIErr := validateLockQueryParams(vars)
 | 
						|
	if adminAPIErr != ErrNone {
 | 
						|
		writeErrorResponse(w, adminAPIErr, r.URL)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Fetch lock information of locks matching bucket/prefix that
 | 
						|
	// are available since relTime.
 | 
						|
	volLocks, err := listPeerLocksInfo(globalAdminPeers, bucket, prefix, relTime)
 | 
						|
	if err != nil {
 | 
						|
		writeErrorResponse(w, ErrInternalError, r.URL)
 | 
						|
		errorIf(err, "Failed to fetch lock information from remote nodes.")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Marshal list of locks as json.
 | 
						|
	jsonBytes, err := json.Marshal(volLocks)
 | 
						|
	if err != nil {
 | 
						|
		writeErrorResponse(w, ErrInternalError, r.URL)
 | 
						|
		errorIf(err, "Failed to marshal lock information into json.")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Remove lock matching bucket/prefix older than relTime.
 | 
						|
	for _, volLock := range volLocks {
 | 
						|
		globalNSMutex.ForceUnlock(volLock.Bucket, volLock.Object)
 | 
						|
	}
 | 
						|
 | 
						|
	// Reply with list of locks cleared, as json.
 | 
						|
	writeSuccessResponseJSON(w, jsonBytes)
 | 
						|
}
 |