1
0
mirror of https://github.com/gluster/glusterd2.git synced 2026-02-05 12:45:38 +01:00
Files
glusterd2/pkg/utils/utils.go
Aravinda VK 552d07b7d9 lvm and fs utils code refactor
Moved lvm related functions from `$SRC/glusterd2/snapshot/lvm`
and `$SRC/plugins/device/deviceutils/` to `$SRC/pkg/lvmutils`

Also moved fs related functions from `plugins/deviceutils` to
`$SRC/pkg/fsutils`.

Fixes: #1187
Signed-off-by: Aravinda VK <avishwan@redhat.com>
2018-11-22 22:38:37 +05:30

248 lines
5.2 KiB
Go

package utils
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"net"
"net/http"
"os"
"os/exec"
"reflect"
"runtime"
"strings"
"syscall"
"golang.org/x/sys/unix"
"github.com/gluster/glusterd2/pkg/errors"
log "github.com/sirupsen/logrus"
)
// constants to convert respective size into bytes.
const (
KB = 1000
KiB = 1024
MB = 1000 * KB
MiB = 1024 * KiB
GB = 1000 * MB
GiB = 1024 * MiB
TB = 1000 * GB
TiB = 1024 * GiB
)
// IsLocalAddress checks whether a given host/IP is local
// Does lookup only after string matching IP addresses
func IsLocalAddress(address string) (bool, error) {
var host string
host, _, _ = net.SplitHostPort(address)
if host == "" {
host = address
}
localNames := []string{"127.0.0.1", "localhost", "::1"}
for _, name := range localNames {
if host == name {
return true, nil
}
}
laddrs, e := net.InterfaceAddrs()
if e != nil {
return false, e
}
var lips []net.IP
for _, laddr := range laddrs {
lipa := laddr.(*net.IPNet)
lips = append(lips, lipa.IP)
}
for _, ip := range lips {
if host == ip.String() {
return true, nil
}
}
rips, e := net.LookupIP(host)
if e != nil {
return false, e
}
for _, rip := range rips {
for _, lip := range lips {
if lip.Equal(rip) {
return true, nil
}
}
}
return false, nil
}
// ParseHostAndBrickPath parses the host & brick path out of req.Bricks list
func ParseHostAndBrickPath(brickPath string) (string, string, error) {
i := strings.LastIndex(brickPath, ":")
if i == -1 {
log.WithError(errors.ErrInvalidBrickPath).WithField("brick", brickPath)
return "", "", errors.ErrInvalidBrickPath
}
hostname := brickPath[0:i]
path := brickPath[i+1:]
return hostname, path, nil
}
// InitDir creates directory path and checks if files can be created in it.
// Returns error if path is not a directory or if directory doesn't have
// write permission.
func InitDir(path string) error {
if err := os.MkdirAll(path, os.ModeDir|os.ModePerm); err != nil {
log.WithError(err).WithField("path", path).Debug(
"failed to create directory")
return err
}
if err := unix.Access(path, unix.W_OK); err != nil {
log.WithError(err).WithField("path", path).Debug(
"directory does not have write permission")
return err
}
return nil
}
// GetLocalIP will give local IP address of this node
func GetLocalIP() (string, error) {
addrs, err := net.InterfaceAddrs()
if err != nil {
return "", err
}
for _, address := range addrs {
// check the address type and if it is not a loopback then return it
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
return ipnet.IP.String(), nil
}
if ipnet.IP.To16() != nil {
return ipnet.IP.String(), nil
}
}
}
return "", errors.ErrIPAddressNotFound
}
// GetFuncName returns the name of the passed function pointer
func GetFuncName(fn interface{}) string {
return runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
}
// StringInSlice will return true if the given string is present in the
// list of strings provided. Will return false otherwise.
func StringInSlice(query string, list []string) bool {
for _, s := range list {
if s == query {
return true
}
}
return false
}
// IsAddressSame checks is two host addresses are same
func IsAddressSame(host1, host2 string) bool {
if host1 == host2 {
return true
}
addrs1, err := net.LookupHost(host1)
if err != nil {
return false
}
addrs2, err := net.LookupHost(host2)
if err != nil {
return false
}
for _, a := range addrs1 {
if StringInSlice(a, addrs2) {
return true
}
}
return false
}
// ExecuteCommandError represents command execution error
type ExecuteCommandError struct {
ExitStatus int
Errstr string
Err error
}
func (e *ExecuteCommandError) Error() string {
errstr := e.Errstr
if errstr != "" {
errstr = "; " + errstr
}
return e.Err.Error() + errstr
}
func execStderrCombined(err error, stderr *bytes.Buffer) error {
if err == nil {
return nil
}
execErr := ExecuteCommandError{
ExitStatus: -1,
Errstr: stderr.String(),
Err: err,
}
exiterr, ok := err.(*exec.ExitError)
if ok {
status, ok := exiterr.Sys().(syscall.WaitStatus)
if ok {
execErr.ExitStatus = status.ExitStatus()
}
}
return &execErr
}
// ExecuteCommandOutput runs the command and adds additional error information
func ExecuteCommandOutput(cmdName string, arg ...string) ([]byte, error) {
cmd := exec.Command(cmdName, arg...)
var stderr bytes.Buffer
cmd.Stderr = &stderr
out, err := cmd.Output()
if err != nil {
return out, execStderrCombined(err, &stderr)
}
return out, nil
}
// ExecuteCommandRun runs the command and adds additional
// error information
func ExecuteCommandRun(cmdName string, arg ...string) error {
cmd := exec.Command(cmdName, arg...)
var stderr bytes.Buffer
cmd.Stderr = &stderr
return execStderrCombined(cmd.Run(), &stderr)
}
//GenerateQsh generate the hash string to avoid URL tampering
func GenerateQsh(r *http.Request) string {
// qsh URL tampering prevention.
//more info https://developer.atlassian.com/cloud/bitbucket/query-string-hash
claim := r.Method + "&" + r.URL.Path
hash := sha256.New()
hash.Write([]byte(claim))
return hex.EncodeToString(hash.Sum(nil))
}