Merge pull request #52132 from portworx/kubelet_weird_output_fix
Automatic merge from submit-queue (batch tested with PRs 51064, 52132). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.. Kubelet weird output fix **What this PR does / why we need it**: All kube binaries print the following message at the top when executed: ``` 2017/08/28 21:37:12 proto: duplicate proto type registered: google.protobuf.Any 2017/08/28 21:37:12 proto: duplicate proto type registered: google.protobuf.Duration 2017/08/28 21:37:12 proto: duplicate proto type registered: google.protobuf.Timestamp ``` This PR addresses the above issue It involves the following two changes: 1. Updating vendor packages - Removes everything under the repo ``go.pedge.io`` - Updates repo libopenstorage/openstorage (which was using the above package) 2. Updates the portworx volume native driver to adhere to the newly vendor'ed code. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #51452 **Special notes for your reviewer**: I have divided the changes into 2 commits 1. Vendor'ed changes 2. Changes in portworx volume driver. ```release-note Remove duplicate proto errors in kubelet. ```
This commit is contained in:
3
vendor/github.com/libopenstorage/openstorage/api/BUILD
generated
vendored
3
vendor/github.com/libopenstorage/openstorage/api/BUILD
generated
vendored
@@ -10,7 +10,8 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/protobuf/proto:go_default_library",
|
||||
"//vendor/go.pedge.io/pb/go/google/protobuf:go_default_library",
|
||||
"//vendor/github.com/golang/protobuf/ptypes/timestamp:go_default_library",
|
||||
"//vendor/github.com/mohae/deepcopy:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
79
vendor/github.com/libopenstorage/openstorage/api/README.md
generated
vendored
Normal file
79
vendor/github.com/libopenstorage/openstorage/api/README.md
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
# OpenStorage API usage
|
||||
|
||||
Any storage product that uses the openstorage API can be managed via this API. Below are some examples of using this API.
|
||||
|
||||
### Enumerate nodes in a cluster
|
||||
```go
|
||||
|
||||
import (
|
||||
...
|
||||
|
||||
"github.com/libopenstorage/gossip/types"
|
||||
"github.com/libopenstorage/openstorage/api"
|
||||
"github.com/libopenstorage/openstorage/api/client/cluster"
|
||||
)
|
||||
|
||||
type myapp struct {
|
||||
manager cluster.Cluster
|
||||
}
|
||||
|
||||
func (c *myapp) init() {
|
||||
// Choose the default version.
|
||||
// Leave the host blank to use the local UNIX socket, or pass in an IP and a port at which the server is listening on.
|
||||
clnt, err := cluster.NewClusterClient("", cluster.APIVersion)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to initialize client library: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
c.manager = cluster.ClusterManager(clnt)
|
||||
}
|
||||
|
||||
func (c *myapp) listNodes() {
|
||||
cluster, err := c.manager.Enumerate()
|
||||
if err != nil {
|
||||
cmdError(context, fn, err)
|
||||
return
|
||||
}
|
||||
|
||||
// cluster is now a hashmap of nodes... do something useful with it:
|
||||
for _, n := range cluster.Nodes {
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Inspect a volume in a cluster
|
||||
```go
|
||||
|
||||
import (
|
||||
...
|
||||
|
||||
"github.com/libopenstorage/openstorage/api"
|
||||
volumeclient "github.com/libopenstorage/openstorage/api/client/volume"
|
||||
"github.com/libopenstorage/openstorage/volume"
|
||||
)
|
||||
|
||||
type myapp struct {
|
||||
volDriver volume.VolumeDriver
|
||||
}
|
||||
|
||||
func (c *myapp) init() {
|
||||
// Choose the default version.
|
||||
// Leave the host blank to use the local UNIX socket, or pass in an IP and a port at which the server is listening on.
|
||||
clnt, err := volumeclient.NewDriverClient("", v.name, volume.APIVersion)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to initialize client library: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
v.volDriver = volumeclient.VolumeDriver(clnt)
|
||||
}
|
||||
|
||||
func (c *myapp) inspect(id string) {
|
||||
stats, err := v.volDriver.Stats(id, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// stats is an object that has various volume properties and statistics.
|
||||
}
|
||||
```
|
191
vendor/github.com/libopenstorage/openstorage/api/api.go
generated
vendored
191
vendor/github.com/libopenstorage/openstorage/api/api.go
generated
vendored
@@ -2,26 +2,44 @@ package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mohae/deepcopy"
|
||||
)
|
||||
|
||||
// Strings for VolumeSpec
|
||||
const (
|
||||
Name = "name"
|
||||
SpecEphemeral = "ephemeral"
|
||||
SpecShared = "shared"
|
||||
SpecSize = "size"
|
||||
SpecScale = "scale"
|
||||
SpecFilesystem = "fs"
|
||||
SpecBlockSize = "block_size"
|
||||
SpecHaLevel = "repl"
|
||||
SpecPriority = "io_priority"
|
||||
SpecSnapshotInterval = "snap_interval"
|
||||
SpecAggregationLevel = "aggregation_level"
|
||||
SpecDedupe = "dedupe"
|
||||
SpecPassphrase = "passphrase"
|
||||
Name = "name"
|
||||
SpecNodes = "nodes"
|
||||
SpecParent = "parent"
|
||||
SpecEphemeral = "ephemeral"
|
||||
SpecShared = "shared"
|
||||
SpecSticky = "sticky"
|
||||
SpecSecure = "secure"
|
||||
SpecCompressed = "compressed"
|
||||
SpecSize = "size"
|
||||
SpecScale = "scale"
|
||||
SpecFilesystem = "fs"
|
||||
SpecBlockSize = "block_size"
|
||||
SpecHaLevel = "repl"
|
||||
SpecPriority = "io_priority"
|
||||
SpecSnapshotInterval = "snap_interval"
|
||||
SpecSnapshotSchedule = "snap_schedule"
|
||||
SpecAggregationLevel = "aggregation_level"
|
||||
SpecDedupe = "dedupe"
|
||||
SpecPassphrase = "secret_key"
|
||||
SpecAutoAggregationValue = "auto"
|
||||
SpecGroup = "group"
|
||||
SpecGroupEnforce = "fg"
|
||||
SpecZones = "zones"
|
||||
SpecRacks = "racks"
|
||||
SpecRegions = "regions"
|
||||
SpecLabels = "labels"
|
||||
SpecPriorityAlias = "priority_io"
|
||||
SpecIoProfile = "io_profile"
|
||||
)
|
||||
|
||||
// OptionKey specifies a set of recognized query params.
|
||||
@@ -30,6 +48,8 @@ const (
|
||||
OptName = "Name"
|
||||
// OptVolumeID query parameter used to lookup volume by ID.
|
||||
OptVolumeID = "VolumeID"
|
||||
// OptSnapID query parameter used to lookup snapshot by ID.
|
||||
OptSnapID = "SnapID"
|
||||
// OptLabel query parameter used to lookup volume by set of labels.
|
||||
OptLabel = "Label"
|
||||
// OptConfigLabel query parameter used to lookup volume by set of labels.
|
||||
@@ -40,9 +60,16 @@ const (
|
||||
|
||||
// Api client-server Constants
|
||||
const (
|
||||
OsdVolumePath = "osd-volumes"
|
||||
OsdVolumePath = "osd-volumes"
|
||||
OsdSnapshotPath = "osd-snapshot"
|
||||
TimeLayout = "Jan 2 15:04:05 UTC 2006"
|
||||
)
|
||||
|
||||
const (
|
||||
// AutoAggregation value indicates driver to select aggregation level.
|
||||
AutoAggregation = math.MaxUint32
|
||||
)
|
||||
|
||||
// Node describes the state of a node.
|
||||
// It includes the current physical state (CPU, memory, storage, network usage) as
|
||||
// well as the containers running on the system.
|
||||
@@ -56,6 +83,7 @@ type Node struct {
|
||||
Status Status
|
||||
GenNumber uint64
|
||||
Disks map[string]StorageResource
|
||||
Pools []StoragePool
|
||||
MgmtIp string
|
||||
DataIp string
|
||||
Timestamp time.Time
|
||||
@@ -66,6 +94,17 @@ type Node struct {
|
||||
NodeLabels map[string]string
|
||||
}
|
||||
|
||||
type FluentDConfig struct {
|
||||
IP string `json:"ip"`
|
||||
Port string `json:"port"`
|
||||
}
|
||||
|
||||
type TunnelConfig struct {
|
||||
Key string `json:"key"`
|
||||
Cert string `json:"cert"`
|
||||
Endpoint string `json:"tunnel_endpoint"`
|
||||
}
|
||||
|
||||
// Cluster represents the state of the cluster.
|
||||
type Cluster struct {
|
||||
Status Status
|
||||
@@ -79,6 +118,18 @@ type Cluster struct {
|
||||
|
||||
// Nodes is an array of all the nodes in the cluster.
|
||||
Nodes []Node
|
||||
|
||||
// Logging url for the cluster.
|
||||
LoggingURL string
|
||||
|
||||
// Management url for the cluster
|
||||
ManagementURL string
|
||||
|
||||
// FluentD Host for the cluster
|
||||
FluentDConfig FluentDConfig
|
||||
|
||||
// TunnelConfig for the cluster [key, cert, endpoint]
|
||||
TunnelConfig TunnelConfig
|
||||
}
|
||||
|
||||
// StatPoint represents the basic structure of a single Stat reported
|
||||
@@ -95,69 +146,97 @@ type StatPoint struct {
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
// DriverTypeSimpleValueOf returns the string format of DriverType
|
||||
func DriverTypeSimpleValueOf(s string) (DriverType, error) {
|
||||
obj, err := simpleValueOf("driver_type", DriverType_value, s)
|
||||
return DriverType(obj), err
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of DriverType
|
||||
func (x DriverType) SimpleString() string {
|
||||
return simpleString("driver_type", DriverType_name, int32(x))
|
||||
}
|
||||
|
||||
// FSTypeSimpleValueOf returns the string format of FSType
|
||||
func FSTypeSimpleValueOf(s string) (FSType, error) {
|
||||
obj, err := simpleValueOf("fs_type", FSType_value, s)
|
||||
return FSType(obj), err
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of DriverType
|
||||
func (x FSType) SimpleString() string {
|
||||
return simpleString("fs_type", FSType_name, int32(x))
|
||||
}
|
||||
|
||||
// CosTypeSimpleValueOf returns the string format of CosType
|
||||
func CosTypeSimpleValueOf(s string) (CosType, error) {
|
||||
obj, err := simpleValueOf("cos_type", CosType_value, s)
|
||||
return CosType(obj), err
|
||||
obj, exists := CosType_value[strings.ToUpper(s)]
|
||||
if !exists {
|
||||
return -1, fmt.Errorf("Invalid cos value: %s", s)
|
||||
}
|
||||
return CosType(obj), nil
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of CosType
|
||||
func (x CosType) SimpleString() string {
|
||||
return simpleString("cos_type", CosType_name, int32(x))
|
||||
}
|
||||
|
||||
// GraphDriverChangeTypeSimpleValueOf returns the string format of GraphDriverChangeType
|
||||
func GraphDriverChangeTypeSimpleValueOf(s string) (GraphDriverChangeType, error) {
|
||||
obj, err := simpleValueOf("graph_driver_change_type", GraphDriverChangeType_value, s)
|
||||
return GraphDriverChangeType(obj), err
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of GraphDriverChangeType
|
||||
func (x GraphDriverChangeType) SimpleString() string {
|
||||
return simpleString("graph_driver_change_type", GraphDriverChangeType_name, int32(x))
|
||||
}
|
||||
|
||||
// VolumeActionParamSimpleValueOf returns the string format of VolumeAction
|
||||
func VolumeActionParamSimpleValueOf(s string) (VolumeActionParam, error) {
|
||||
obj, err := simpleValueOf("volume_action_param", VolumeActionParam_value, s)
|
||||
return VolumeActionParam(obj), err
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of VolumeAction
|
||||
func (x VolumeActionParam) SimpleString() string {
|
||||
return simpleString("volume_action_param", VolumeActionParam_name, int32(x))
|
||||
}
|
||||
|
||||
// VolumeStateSimpleValueOf returns the string format of VolumeState
|
||||
func VolumeStateSimpleValueOf(s string) (VolumeState, error) {
|
||||
obj, err := simpleValueOf("volume_state", VolumeState_value, s)
|
||||
return VolumeState(obj), err
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of VolumeState
|
||||
func (x VolumeState) SimpleString() string {
|
||||
return simpleString("volume_state", VolumeState_name, int32(x))
|
||||
}
|
||||
|
||||
// VolumeStatusSimpleValueOf returns the string format of VolumeStatus
|
||||
func VolumeStatusSimpleValueOf(s string) (VolumeStatus, error) {
|
||||
obj, err := simpleValueOf("volume_status", VolumeStatus_value, s)
|
||||
return VolumeStatus(obj), err
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of VolumeStatus
|
||||
func (x VolumeStatus) SimpleString() string {
|
||||
return simpleString("volume_status", VolumeStatus_name, int32(x))
|
||||
}
|
||||
|
||||
// IoProfileSimpleValueOf returns the string format of IoProfile
|
||||
func IoProfileSimpleValueOf(s string) (IoProfile, error) {
|
||||
obj, err := simpleValueOf("io_profile", IoProfile_value, s)
|
||||
return IoProfile(obj), err
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of IoProfile
|
||||
func (x IoProfile) SimpleString() string {
|
||||
return simpleString("io_profile", IoProfile_name, int32(x))
|
||||
}
|
||||
|
||||
func simpleValueOf(typeString string, valueMap map[string]int32, s string) (int32, error) {
|
||||
obj, ok := valueMap[strings.ToUpper(fmt.Sprintf("%s_%s", typeString, s))]
|
||||
if !ok {
|
||||
@@ -178,6 +257,7 @@ func toSec(ms uint64) uint64 {
|
||||
return ms / 1000
|
||||
}
|
||||
|
||||
// WriteThroughput returns the write throughput
|
||||
func (v *Stats) WriteThroughput() uint64 {
|
||||
if v.IntervalMs == 0 {
|
||||
return 0
|
||||
@@ -185,6 +265,7 @@ func (v *Stats) WriteThroughput() uint64 {
|
||||
return (v.WriteBytes) / toSec(v.IntervalMs)
|
||||
}
|
||||
|
||||
// ReadThroughput returns the read throughput
|
||||
func (v *Stats) ReadThroughput() uint64 {
|
||||
if v.IntervalMs == 0 {
|
||||
return 0
|
||||
@@ -192,17 +273,93 @@ func (v *Stats) ReadThroughput() uint64 {
|
||||
return (v.ReadBytes) / toSec(v.IntervalMs)
|
||||
}
|
||||
|
||||
// Latency returns latency
|
||||
func (v *Stats) Latency() uint64 {
|
||||
ops := v.Writes + v.Reads
|
||||
if ops == 0 {
|
||||
return 0
|
||||
}
|
||||
return (uint64)((v.IoMs * 1000) / (v.Writes + v.Reads))
|
||||
return (uint64)((v.IoMs * 1000) / ops)
|
||||
}
|
||||
|
||||
// Read latency returns avg. time required for read operation to complete
|
||||
func (v *Stats) ReadLatency() uint64 {
|
||||
if v.Reads == 0 {
|
||||
return 0
|
||||
}
|
||||
return (uint64)((v.ReadMs * 1000) / v.Reads)
|
||||
}
|
||||
|
||||
// Write latency returns avg. time required for write operation to complete
|
||||
func (v *Stats) WriteLatency() uint64 {
|
||||
if v.Writes == 0 {
|
||||
return 0
|
||||
}
|
||||
return (uint64)((v.WriteMs * 1000) / v.Writes)
|
||||
}
|
||||
|
||||
// Iops returns iops
|
||||
func (v *Stats) Iops() uint64 {
|
||||
if v.IntervalMs == 0 {
|
||||
return 0
|
||||
}
|
||||
return (v.Writes + v.Reads) / toSec(v.IntervalMs)
|
||||
}
|
||||
|
||||
// Scaled returns true if the volume is scaled.
|
||||
func (v *Volume) Scaled() bool {
|
||||
return v.Spec.Scale > 1
|
||||
}
|
||||
|
||||
// Contains returns true if mid is a member of volume's replication set.
|
||||
func (m *Volume) Contains(mid string) bool {
|
||||
rsets := m.GetReplicaSets()
|
||||
for _, rset := range rsets {
|
||||
for _, node := range rset.Nodes {
|
||||
if node == mid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Copy makes a deep copy of VolumeSpec
|
||||
func (s *VolumeSpec) Copy() *VolumeSpec {
|
||||
spec := *s
|
||||
if s.VolumeLabels != nil {
|
||||
spec.VolumeLabels = make(map[string]string)
|
||||
for k, v := range s.VolumeLabels {
|
||||
spec.VolumeLabels[k] = v
|
||||
}
|
||||
}
|
||||
if s.ReplicaSet != nil {
|
||||
spec.ReplicaSet = &ReplicaSet{Nodes: make([]string, len(s.ReplicaSet.Nodes))}
|
||||
copy(spec.ReplicaSet.Nodes, s.ReplicaSet.Nodes)
|
||||
}
|
||||
return &spec
|
||||
}
|
||||
|
||||
// Copy makes a deep copy of Node
|
||||
func (s *Node) Copy() *Node {
|
||||
localCopy := deepcopy.Copy(*s)
|
||||
nodeCopy := localCopy.(Node)
|
||||
return &nodeCopy
|
||||
}
|
||||
|
||||
func (v Volume) IsClone() bool {
|
||||
return v.Source != nil && len(v.Source.Parent) != 0 && !v.Readonly
|
||||
}
|
||||
|
||||
func (v Volume) IsSnapshot() bool {
|
||||
return v.Source != nil && len(v.Source.Parent) != 0 && v.Readonly
|
||||
}
|
||||
|
||||
func (v Volume) DisplayId() string {
|
||||
if v.Locator != nil {
|
||||
return fmt.Sprintf("%s (%s)", v.Locator.Name, v.Id)
|
||||
} else {
|
||||
return v.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
856
vendor/github.com/libopenstorage/openstorage/api/api.pb.go
generated
vendored
856
vendor/github.com/libopenstorage/openstorage/api/api.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
183
vendor/github.com/libopenstorage/openstorage/api/api.proto
generated
vendored
183
vendor/github.com/libopenstorage/openstorage/api/api.proto
generated
vendored
@@ -90,6 +90,13 @@ enum CosType {
|
||||
HIGH = 3;
|
||||
}
|
||||
|
||||
enum IoProfile {
|
||||
IO_PROFILE_SEQUENTIAL = 0;
|
||||
IO_PROFILE_RANDOM= 1;
|
||||
IO_PROFILE_DB = 2;
|
||||
IO_PROFILE_DB_REMOTE = 3;
|
||||
}
|
||||
|
||||
// VolumeState represents the state of a volume.
|
||||
enum VolumeState {
|
||||
VOLUME_STATE_NONE = 0;
|
||||
@@ -108,6 +115,10 @@ enum VolumeState {
|
||||
// Volume is deleted, it will remain in this state
|
||||
// while resources are asynchronously reclaimed
|
||||
VOLUME_STATE_DELETED = 7;
|
||||
// Volume is trying to be detached
|
||||
VOLUME_STATE_TRY_DETACHING = 8;
|
||||
// Volume is undergoing restore
|
||||
VOLUME_STATE_RESTORE = 9;
|
||||
}
|
||||
|
||||
// VolumeStatus represents a health status for a volume.
|
||||
@@ -138,6 +149,15 @@ enum ClusterNotify {
|
||||
CLUSTER_NOTIFY_DOWN = 0;
|
||||
}
|
||||
|
||||
enum AttachState {
|
||||
// Attached and available externally
|
||||
ATTACH_STATE_EXTERNAL = 0;
|
||||
// Attached but only available internally
|
||||
ATTACH_STATE_INTERNAL = 1;
|
||||
// Switching from External to Internal
|
||||
ATTACH_STATE_INTERNAL_SWITCH = 2;
|
||||
}
|
||||
|
||||
// StorageResource groups properties of a storage device.
|
||||
message StorageResource {
|
||||
// Id is the LUN identifier.
|
||||
@@ -166,6 +186,24 @@ message StorageResource {
|
||||
google.protobuf.Timestamp last_scan = 12;
|
||||
}
|
||||
|
||||
// StoragePool groups different storage devices based on their CosType
|
||||
message StoragePool {
|
||||
// ID pool ID
|
||||
int32 ID = 1;
|
||||
// Cos reflects the capabilities of this drive pool
|
||||
CosType Cos = 2;
|
||||
// Medium underlying storage type
|
||||
StorageMedium Medium = 3;
|
||||
// RaidLevel storage raid level
|
||||
string RaidLevel = 4;
|
||||
// TotalSize of the pool
|
||||
uint64 TotalSize = 7;
|
||||
// Used size of the pool
|
||||
uint64 Used = 8;
|
||||
// Labels is a list of user defined name-value pairs
|
||||
map<string, string> labels = 9;
|
||||
}
|
||||
|
||||
// VolumeLocator is a structure that is attached to a volume
|
||||
// and is used to carry opaque metadata.
|
||||
message VolumeLocator {
|
||||
@@ -183,89 +221,115 @@ message Source {
|
||||
string seed = 2;
|
||||
}
|
||||
|
||||
message Group {
|
||||
// Id common identifier across volumes that have the same group.
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
// VolumeSpec has the properties needed to create a volume.
|
||||
message VolumeSpec {
|
||||
// Ephemeral storage
|
||||
bool ephemeral = 1;
|
||||
// Thin provisioned volume size in bytes
|
||||
// Size specifies the thin provisioned volume size.
|
||||
uint64 size = 2;
|
||||
// Format disk with this FSType
|
||||
// Format specifies the filesystem for this volume.
|
||||
FSType format = 3;
|
||||
// Block size for filesystem
|
||||
// BlockSize for the filesystem.
|
||||
int64 block_size = 4;
|
||||
// Specifies the number of nodes that are
|
||||
// allowed to fail, and yet data is available
|
||||
// A value of 0 implies that data is not erasure coded,
|
||||
// a failure of a node will lead to data loss
|
||||
// HaLevel specifies the number of copies of data.
|
||||
int64 ha_level = 5;
|
||||
// The COS, 1 to 9
|
||||
// Cos specifies the relative class of service.
|
||||
CosType cos = 6;
|
||||
// Perform dedupe on this disk
|
||||
bool dedupe = 7;
|
||||
// IoProfile provides a hint about application using this volume.
|
||||
IoProfile io_profile = 7;
|
||||
// Dedupe specifies if the volume data is to be de-duplicated.
|
||||
bool dedupe = 8;
|
||||
// SnapshotInterval in minutes, set to 0 to disable snapshots
|
||||
uint32 snapshot_interval = 8;
|
||||
// Volume configuration labels
|
||||
map<string, string> volume_labels = 9;
|
||||
uint32 snapshot_interval = 9;
|
||||
// VolumeLabels configuration labels
|
||||
map<string, string> volume_labels = 10;
|
||||
// Shared is true if this volume can be remotely accessed.
|
||||
bool shared = 10;
|
||||
// ReplicaSet is the desired replicaSet the volume want to be placed.
|
||||
ReplicaSet replica_set = 11;
|
||||
// Specifies the number of parts the volume can be aggregated from.
|
||||
uint32 aggregation_level = 12;
|
||||
bool shared = 11;
|
||||
// ReplicaSet is the desired set of nodes for the volume data.
|
||||
ReplicaSet replica_set = 12;
|
||||
// Aggregatiokn level Specifies the number of parts the volume can be aggregated from.
|
||||
uint32 aggregation_level = 13;
|
||||
// Encrypted is true if this volume will be cryptographically secured.
|
||||
bool encrypted = 13;
|
||||
// User passphrase if this is an encrypted volume
|
||||
string passphrase = 14;
|
||||
// SnapshotSchedule
|
||||
string snapshot_schedule = 15;
|
||||
bool encrypted = 14;
|
||||
// Passphrase for an encrypted volume
|
||||
string passphrase = 15;
|
||||
// SnapshotSchedule a well known string that specifies when snapshots should be taken.
|
||||
string snapshot_schedule = 16;
|
||||
// Scale allows autocreation of volumes.
|
||||
uint32 scale = 16;
|
||||
uint32 scale = 17;
|
||||
// Sticky volumes cannot be deleted until the flag is removed.
|
||||
bool sticky = 18;
|
||||
// Group identifies a consistency group
|
||||
Group group = 21;
|
||||
// GroupEnforced is true if consistency group creation is enforced.
|
||||
bool group_enforced = 22;
|
||||
// Compressed is true if this volume is to be compressed.
|
||||
bool compressed = 23;
|
||||
}
|
||||
|
||||
// Set of machine IDs (nodes) to which part of this volume is erasure coded - for clustered storage arrays
|
||||
// ReplicaSet set of machine IDs (nodes) to which part of this volume is erasure
|
||||
// coded - for clustered storage arrays
|
||||
message ReplicaSet {
|
||||
repeated string nodes = 1;
|
||||
}
|
||||
|
||||
// List of name value mapping of driver specific runtime information.
|
||||
// RuntimeStateMap is a list of name value mapping of driver specific runtime
|
||||
// information.
|
||||
message RuntimeStateMap {
|
||||
map<string, string> runtime_state = 1;
|
||||
}
|
||||
|
||||
// Volume represents a live, created volume.
|
||||
// Volume represents an abstract storage volume.
|
||||
// Volume represents an abstract storage volume.
|
||||
message Volume {
|
||||
// Self referential volume ID
|
||||
// Self referential volume ID.
|
||||
string id = 1;
|
||||
// Source specified seed data for the volume.
|
||||
Source source = 2;
|
||||
bool readonly = 3;
|
||||
// Group volumes in the same group have the same group id.
|
||||
Group group = 3;
|
||||
// Readonly is true if this volume is to be mounted with readonly access.
|
||||
bool readonly = 4;
|
||||
// User specified locator
|
||||
VolumeLocator locator = 4;
|
||||
VolumeLocator locator = 5;
|
||||
// Volume creation time
|
||||
google.protobuf.Timestamp ctime = 5;
|
||||
google.protobuf.Timestamp ctime = 6;
|
||||
// User specified VolumeSpec
|
||||
VolumeSpec spec = 6;
|
||||
// Volume usage
|
||||
uint64 usage = 7;
|
||||
// Time when an integrity check for run
|
||||
google.protobuf.Timestamp last_scan = 8;
|
||||
// Format FSType type if any
|
||||
FSType format = 9;
|
||||
VolumeStatus status = 10;
|
||||
VolumeState state = 11;
|
||||
// Machine ID (node) on which this volume is attached
|
||||
// Machine ID is a node instance identifier for clustered systems.
|
||||
string attached_on = 12;
|
||||
string device_path = 14;
|
||||
repeated string attach_path = 15;
|
||||
// List of ReplicaSets which provide storage for this volume, for clustered storage arrays
|
||||
repeated ReplicaSet replica_sets = 16;
|
||||
// Last recorded error
|
||||
string error = 17;
|
||||
// List of name value mapping of driver specific runtime information.
|
||||
repeated RuntimeStateMap runtime_state = 18;
|
||||
string secure_device_path = 19;
|
||||
// BackgroundProcessing is true if volume is attached but not by the user
|
||||
bool background_processing = 20;
|
||||
VolumeSpec spec = 7;
|
||||
// Usage is bytes consumed by vtheis volume.
|
||||
uint64 usage = 8;
|
||||
// LastScan is the time when an integrity check was run.
|
||||
google.protobuf.Timestamp last_scan = 9;
|
||||
// Format specifies the filesytem for this volume.
|
||||
FSType format = 10;
|
||||
// Status is the availability status of this volume.
|
||||
VolumeStatus status = 11;
|
||||
// State is the current runtime state of this volume.
|
||||
VolumeState state = 12;
|
||||
// AttachedOn is the node instance identifier for clustered systems.
|
||||
string attached_on = 13;
|
||||
// AttachedState shows whether the device is attached for internal or external use.
|
||||
AttachState attached_state = 14;
|
||||
// DevicePath is the device exported by block device implementations.
|
||||
string device_path = 15;
|
||||
// SecureDevicePath is the device path for an encrypted volume.
|
||||
string secure_device_path = 16;
|
||||
// AttachPath is the mounted path in the host namespace.
|
||||
repeated string attach_path = 17;
|
||||
// AttachInfo is a list of name value mappings that provides attach information.
|
||||
map<string, string> attach_info = 18;
|
||||
// ReplicatSets storage for this volumefor clustered storage arrays.
|
||||
repeated ReplicaSet replica_sets = 19;
|
||||
// RuntimeState is a lst of name value mapping of driver specific runtime
|
||||
// information.
|
||||
repeated RuntimeStateMap runtime_state = 20;
|
||||
// Error is the Last recorded error.
|
||||
string error = 21;
|
||||
}
|
||||
|
||||
message Stats {
|
||||
@@ -308,6 +372,8 @@ message Alert {
|
||||
bool cleared = 8;
|
||||
// TTL in seconds for this Alert
|
||||
uint64 ttl = 9;
|
||||
// UniqueTag helps identify a unique alert for a given resouce
|
||||
string unique_tag = 10;
|
||||
}
|
||||
|
||||
message Alerts {
|
||||
@@ -339,9 +405,13 @@ message VolumeStateAction {
|
||||
VolumeActionParam attach = 1;
|
||||
// Mount or unmount volume
|
||||
VolumeActionParam mount = 2;
|
||||
// MountPath Path where the device is mounted
|
||||
string mount_path = 3;
|
||||
// Device path returned in attach
|
||||
// DevicePath Path returned in attach
|
||||
string device_path = 4;
|
||||
// UnmountBeforeDetach is used to check whether unmount should be done before
|
||||
// a detach
|
||||
bool unmount_before_detach = 5;
|
||||
}
|
||||
|
||||
message VolumeSetRequest {
|
||||
@@ -351,6 +421,9 @@ message VolumeSetRequest {
|
||||
VolumeSpec spec = 2;
|
||||
// State modification on this volume.
|
||||
VolumeStateAction action = 3;
|
||||
// additional options
|
||||
// required for the Set operation.
|
||||
map<string, string> options = 4;
|
||||
}
|
||||
|
||||
message VolumeSetResponse {
|
||||
|
101
vendor/github.com/libopenstorage/openstorage/api/client/client.go
generated
vendored
101
vendor/github.com/libopenstorage/openstorage/api/client/client.go
generated
vendored
@@ -16,7 +16,7 @@ var (
|
||||
)
|
||||
|
||||
// NewClient returns a new REST client for specified server.
|
||||
func NewClient(host string, version string) (*Client, error) {
|
||||
func NewClient(host, version, userAgent string) (*Client, error) {
|
||||
baseURL, err := url.Parse(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -25,14 +25,48 @@ func NewClient(host string, version string) (*Client, error) {
|
||||
baseURL.Path = "/"
|
||||
}
|
||||
unix2HTTP(baseURL)
|
||||
hClient := getHTTPClient(host)
|
||||
if hClient == nil {
|
||||
return nil, fmt.Errorf("Unable to parse provided url: %v", host)
|
||||
}
|
||||
c := &Client{
|
||||
base: baseURL,
|
||||
version: version,
|
||||
httpClient: getHttpClient(host),
|
||||
base: baseURL,
|
||||
version: version,
|
||||
httpClient: hClient,
|
||||
authstring: "",
|
||||
accesstoken: "",
|
||||
userAgent: fmt.Sprintf("%v/%v", userAgent, version),
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// NewAuthClient returns a new REST client for specified server.
|
||||
func NewAuthClient(host, version, authstring, accesstoken, userAgent string) (*Client, error) {
|
||||
baseURL, err := url.Parse(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if baseURL.Path == "" {
|
||||
baseURL.Path = "/"
|
||||
}
|
||||
unix2HTTP(baseURL)
|
||||
hClient := getHTTPClient(host)
|
||||
if hClient == nil {
|
||||
return nil, fmt.Errorf("Unable to parse provided url: %v", host)
|
||||
}
|
||||
c := &Client{
|
||||
base: baseURL,
|
||||
version: version,
|
||||
httpClient: hClient,
|
||||
authstring: authstring,
|
||||
accesstoken: accesstoken,
|
||||
userAgent: fmt.Sprintf("%v/%v", userAgent, version),
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// GetUnixServerPath returns a unix domain socket prepended with the
|
||||
// provided path.
|
||||
func GetUnixServerPath(socketName string, paths ...string) string {
|
||||
serverPath := "unix://"
|
||||
for _, path := range paths {
|
||||
@@ -42,13 +76,15 @@ func GetUnixServerPath(socketName string, paths ...string) string {
|
||||
return serverPath
|
||||
}
|
||||
|
||||
|
||||
// Client is an HTTP REST wrapper. Use one of Get/Post/Put/Delete to get a request
|
||||
// object.
|
||||
type Client struct {
|
||||
base *url.URL
|
||||
version string
|
||||
httpClient *http.Client
|
||||
base *url.URL
|
||||
version string
|
||||
httpClient *http.Client
|
||||
authstring string
|
||||
accesstoken string
|
||||
userAgent string
|
||||
}
|
||||
|
||||
// Status sends a Status request at the /status REST endpoint.
|
||||
@@ -58,7 +94,7 @@ func (c *Client) Status() (*Status, error) {
|
||||
return status, err
|
||||
}
|
||||
|
||||
// Version send a request at the /versions REST endpoint.
|
||||
// Versions send a request at the /versions REST endpoint.
|
||||
func (c *Client) Versions(endpoint string) ([]string, error) {
|
||||
versions := []string{}
|
||||
err := c.Get().Resource(endpoint + "/versions").Do().Unmarshal(&versions)
|
||||
@@ -67,22 +103,22 @@ func (c *Client) Versions(endpoint string) ([]string, error) {
|
||||
|
||||
// Get returns a Request object setup for GET call.
|
||||
func (c *Client) Get() *Request {
|
||||
return NewRequest(c.httpClient, c.base, "GET", c.version)
|
||||
return NewRequest(c.httpClient, c.base, "GET", c.version, c.authstring, c.userAgent)
|
||||
}
|
||||
|
||||
// Post returns a Request object setup for POST call.
|
||||
func (c *Client) Post() *Request {
|
||||
return NewRequest(c.httpClient, c.base, "POST", c.version)
|
||||
return NewRequest(c.httpClient, c.base, "POST", c.version, c.authstring, c.userAgent)
|
||||
}
|
||||
|
||||
// Put returns a Request object setup for PUT call.
|
||||
func (c *Client) Put() *Request {
|
||||
return NewRequest(c.httpClient, c.base, "PUT", c.version)
|
||||
return NewRequest(c.httpClient, c.base, "PUT", c.version, c.authstring, c.userAgent)
|
||||
}
|
||||
|
||||
// Put returns a Request object setup for DELETE call.
|
||||
// Delete returns a Request object setup for DELETE call.
|
||||
func (c *Client) Delete() *Request {
|
||||
return NewRequest(c.httpClient, c.base, "DELETE", c.version)
|
||||
return NewRequest(c.httpClient, c.base, "DELETE", c.version, c.authstring, c.userAgent)
|
||||
}
|
||||
|
||||
func unix2HTTP(u *url.URL) {
|
||||
@@ -94,7 +130,12 @@ func unix2HTTP(u *url.URL) {
|
||||
}
|
||||
}
|
||||
|
||||
func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *http.Client {
|
||||
func newHTTPClient(
|
||||
u *url.URL,
|
||||
tlsConfig *tls.Config,
|
||||
timeout time.Duration,
|
||||
responseTimeout time.Duration,
|
||||
) *http.Client {
|
||||
httpTransport := &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
@@ -114,28 +155,24 @@ func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *ht
|
||||
}
|
||||
}
|
||||
|
||||
return &http.Client{Transport: httpTransport}
|
||||
return &http.Client{Transport: httpTransport, Timeout: responseTimeout}
|
||||
}
|
||||
|
||||
func getHttpClient(host string) *http.Client {
|
||||
func getHTTPClient(host string) *http.Client {
|
||||
cacheLock.Lock()
|
||||
defer cacheLock.Unlock()
|
||||
c, ok := httpCache[host]
|
||||
if !ok {
|
||||
cacheLock.Lock()
|
||||
defer cacheLock.Unlock()
|
||||
c, ok = httpCache[host]
|
||||
if !ok {
|
||||
u, err := url.Parse(host)
|
||||
if err != nil {
|
||||
// TODO(pedge): clean up
|
||||
fmt.Println("Failed to parse into url", host)
|
||||
return nil
|
||||
}
|
||||
if u.Path == "" {
|
||||
u.Path = "/"
|
||||
}
|
||||
c = newHTTPClient(u, nil, 10*time.Second)
|
||||
httpCache[host] = c
|
||||
u, err := url.Parse(host)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if u.Path == "" {
|
||||
u.Path = "/"
|
||||
}
|
||||
c = newHTTPClient(u, nil, 10*time.Second, 5*time.Minute)
|
||||
httpCache[host] = c
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
36
vendor/github.com/libopenstorage/openstorage/api/client/request.go
generated
vendored
36
vendor/github.com/libopenstorage/openstorage/api/client/request.go
generated
vendored
@@ -11,6 +11,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// Request is contructed iteratively by the client and finally dispatched.
|
||||
@@ -31,6 +32,8 @@ type Request struct {
|
||||
req *http.Request
|
||||
resp *http.Response
|
||||
timeout time.Duration
|
||||
authstring string
|
||||
accesstoken string
|
||||
}
|
||||
|
||||
// Response is a representation of HTTP response received from the server.
|
||||
@@ -48,14 +51,17 @@ type Status struct {
|
||||
}
|
||||
|
||||
// NewRequest instance
|
||||
func NewRequest(client *http.Client, base *url.URL, verb string, version string) *Request {
|
||||
return &Request{
|
||||
func NewRequest(client *http.Client, base *url.URL, verb string, version string, authstring, userAgent string) *Request {
|
||||
r := &Request{
|
||||
client: client,
|
||||
verb: verb,
|
||||
base: base,
|
||||
path: base.Path,
|
||||
version: version,
|
||||
authstring: authstring,
|
||||
}
|
||||
r.SetHeader("User-Agent", userAgent)
|
||||
return r
|
||||
}
|
||||
|
||||
func checkExists(mustExist string, before string) error {
|
||||
@@ -251,8 +257,19 @@ func (r *Request) Do() *Response {
|
||||
if r.headers == nil {
|
||||
r.headers = http.Header{}
|
||||
}
|
||||
|
||||
req.Header = r.headers
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Date", time.Now().String())
|
||||
|
||||
if len(r.authstring) > 0 {
|
||||
req.Header.Set("Authorization", "Basic "+ r.authstring)
|
||||
}
|
||||
|
||||
if len(r.accesstoken) > 0 {
|
||||
req.Header.Set("Access-Token", r.accesstoken)
|
||||
}
|
||||
|
||||
resp, err = r.client.Do(req)
|
||||
if err != nil {
|
||||
return &Response{err: err}
|
||||
@@ -295,10 +312,21 @@ func (r Response) Error() error {
|
||||
return r.err
|
||||
}
|
||||
|
||||
// FormatError formats the error
|
||||
func (r Response) FormatError() error {
|
||||
if len(r.body) == 0 {
|
||||
return fmt.Errorf("Error: %v", r.err)
|
||||
} else {
|
||||
return fmt.Errorf("HTTP-%d: %s", r.statusCode, string(r.body))
|
||||
}
|
||||
return fmt.Errorf("HTTP-%d: %s", r.statusCode, string(r.body))
|
||||
}
|
||||
|
||||
func digest(method string, path string) string {
|
||||
now := time.Now().String()
|
||||
|
||||
s1 := rand.NewSource(time.Now().UnixNano())
|
||||
r1 := rand.New(s1)
|
||||
|
||||
nonce := r1.Intn(10)
|
||||
|
||||
return method + "+" + path + "+" + now + "+" + strconv.Itoa(nonce)
|
||||
}
|
||||
|
44
vendor/github.com/libopenstorage/openstorage/api/client/volume/client.go
generated
vendored
44
vendor/github.com/libopenstorage/openstorage/api/client/volume/client.go
generated
vendored
@@ -195,6 +195,21 @@ func (v *volumeClient) Snapshot(volumeID string, readonly bool,
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Restore specified volume to given snapshot state
|
||||
func (v *volumeClient) Restore(volumeID string, snapID string) error {
|
||||
response := &api.VolumeResponse{}
|
||||
req := v.c.Post().Resource(snapPath + "/restore").Instance(volumeID)
|
||||
req.QueryOption(api.OptSnapID, snapID)
|
||||
|
||||
if err := req.Do().Unmarshal(response); err != nil {
|
||||
return err
|
||||
}
|
||||
if response.Error != "" {
|
||||
return errors.New(response.Error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stats for specified volume.
|
||||
// Errors ErrEnoEnt may be returned
|
||||
func (v *volumeClient) Stats(
|
||||
@@ -205,21 +220,20 @@ func (v *volumeClient) Stats(
|
||||
req := v.c.Get().Resource(volumePath + "/stats").Instance(volumeID)
|
||||
req.QueryOption(api.OptCumulative, strconv.FormatBool(cumulative))
|
||||
|
||||
if err := req.Do().Unmarshal(stats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err := req.Do().Unmarshal(stats)
|
||||
return stats, err
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// Alerts on this volume.
|
||||
// UsedSize returns allocated volume size.
|
||||
// Errors ErrEnoEnt may be returned
|
||||
func (v *volumeClient) Alerts(volumeID string) (*api.Alerts, error) {
|
||||
alerts := &api.Alerts{}
|
||||
if err := v.c.Get().Resource(volumePath + "/alerts").Instance(volumeID).Do().Unmarshal(alerts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return alerts, nil
|
||||
func (v *volumeClient) UsedSize(
|
||||
volumeID string,
|
||||
) (uint64, error) {
|
||||
var usedSize uint64
|
||||
req := v.c.Get().Resource(volumePath + "/usedsize").Instance(volumeID)
|
||||
err := req.Do().Unmarshal(&usedSize)
|
||||
return usedSize, err
|
||||
}
|
||||
|
||||
// Active Requests on all volume.
|
||||
@@ -289,13 +303,14 @@ func (v *volumeClient) SnapEnumerate(ids []string,
|
||||
// Attach map device to the host.
|
||||
// On success the devicePath specifies location where the device is exported
|
||||
// Errors ErrEnoEnt, ErrVolAttached may be returned.
|
||||
func (v *volumeClient) Attach(volumeID string) (string, error) {
|
||||
func (v *volumeClient) Attach(volumeID string, attachOptions map[string]string) (string, error) {
|
||||
response, err := v.doVolumeSetGetResponse(
|
||||
volumeID,
|
||||
&api.VolumeSetRequest{
|
||||
Action: &api.VolumeStateAction{
|
||||
Attach: api.VolumeActionParam_VOLUME_ACTION_PARAM_ON,
|
||||
},
|
||||
Options: attachOptions,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -313,12 +328,13 @@ func (v *volumeClient) Attach(volumeID string) (string, error) {
|
||||
|
||||
// Detach device from the host.
|
||||
// Errors ErrEnoEnt, ErrVolDetached may be returned.
|
||||
func (v *volumeClient) Detach(volumeID string) error {
|
||||
func (v *volumeClient) Detach(volumeID string, unmountBeforeDetach bool) error {
|
||||
return v.doVolumeSet(
|
||||
volumeID,
|
||||
&api.VolumeSetRequest{
|
||||
Action: &api.VolumeStateAction{
|
||||
Attach: api.VolumeActionParam_VOLUME_ACTION_PARAM_OFF,
|
||||
Attach: api.VolumeActionParam_VOLUME_ACTION_PARAM_OFF,
|
||||
UnmountBeforeDetach: unmountBeforeDetach,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
27
vendor/github.com/libopenstorage/openstorage/api/client/volume/volume.go
generated
vendored
27
vendor/github.com/libopenstorage/openstorage/api/client/volume/volume.go
generated
vendored
@@ -2,9 +2,9 @@ package volume
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/libopenstorage/openstorage/api"
|
||||
"github.com/libopenstorage/openstorage/api/client"
|
||||
"github.com/libopenstorage/openstorage/volume"
|
||||
"github.com/libopenstorage/openstorage/api"
|
||||
)
|
||||
|
||||
// VolumeDriver returns a REST wrapper for the VolumeDriver interface.
|
||||
@@ -12,10 +12,10 @@ func VolumeDriver(c *client.Client) volume.VolumeDriver {
|
||||
return newVolumeClient(c)
|
||||
}
|
||||
|
||||
// NewDriver returns a new REST client of the supplied version for specified driver.
|
||||
// NewAuthDriverClient returns a new REST client of the supplied version for specified driver.
|
||||
// host: REST endpoint [http://<ip>:<port> OR unix://<path-to-unix-socket>]. default: [unix:///var/lib/osd/<driverName>.sock]
|
||||
// version: Volume API version
|
||||
func NewDriverClient(host, driverName, version string) (*client.Client, error) {
|
||||
func NewAuthDriverClient(host, driverName, version, authstring, accesstoken, userAgent string) (*client.Client, error) {
|
||||
if driverName == "" {
|
||||
return nil, fmt.Errorf("Driver Name cannot be empty")
|
||||
}
|
||||
@@ -26,7 +26,24 @@ func NewDriverClient(host, driverName, version string) (*client.Client, error) {
|
||||
// Set the default version
|
||||
version = volume.APIVersion
|
||||
}
|
||||
return client.NewClient(host, version)
|
||||
return client.NewAuthClient(host, version, authstring, accesstoken, userAgent)
|
||||
}
|
||||
|
||||
// NewDriverClient returns a new REST client of the supplied version for specified driver.
|
||||
// host: REST endpoint [http://<ip>:<port> OR unix://<path-to-unix-socket>]. default: [unix:///var/lib/osd/<driverName>.sock]
|
||||
// version: Volume API version
|
||||
func NewDriverClient(host, driverName, version, userAgent string) (*client.Client, error) {
|
||||
if driverName == "" {
|
||||
return nil, fmt.Errorf("Driver Name cannot be empty")
|
||||
}
|
||||
if host == "" {
|
||||
host = client.GetUnixServerPath(driverName, volume.DriverAPIBase)
|
||||
}
|
||||
if version == "" {
|
||||
// Set the default version
|
||||
version = volume.APIVersion
|
||||
}
|
||||
return client.NewClient(host, version, userAgent)
|
||||
}
|
||||
|
||||
// GetSupportedDriverVersions returns a list of supported versions
|
||||
@@ -38,7 +55,7 @@ func GetSupportedDriverVersions(driverName, host string) ([]string, error) {
|
||||
host = client.GetUnixServerPath(driverName, volume.DriverAPIBase)
|
||||
}
|
||||
|
||||
client, err := client.NewClient(host, "")
|
||||
client, err := client.NewClient(host, "", "")
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
1
vendor/github.com/libopenstorage/openstorage/api/spec/BUILD
generated
vendored
1
vendor/github.com/libopenstorage/openstorage/api/spec/BUILD
generated
vendored
@@ -6,6 +6,7 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/libopenstorage/openstorage/api:go_default_library",
|
||||
"//vendor/github.com/libopenstorage/openstorage/pkg/parser:go_default_library",
|
||||
"//vendor/github.com/libopenstorage/openstorage/pkg/units:go_default_library",
|
||||
],
|
||||
)
|
||||
|
225
vendor/github.com/libopenstorage/openstorage/api/spec/spec_handler.go
generated
vendored
225
vendor/github.com/libopenstorage/openstorage/api/spec/spec_handler.go
generated
vendored
@@ -4,8 +4,10 @@ import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/libopenstorage/openstorage/api"
|
||||
"github.com/libopenstorage/openstorage/pkg/parser"
|
||||
"github.com/libopenstorage/openstorage/pkg/units"
|
||||
)
|
||||
|
||||
@@ -16,54 +18,92 @@ type SpecHandler interface {
|
||||
// If the scheduler was unable to pass in the volume spec via the API,
|
||||
// the spec can be passed in via the name in the format:
|
||||
// "key=value;key=value;name=volname"
|
||||
// source is populated if key parent=<volume_id> is specified.
|
||||
// If the spec was parsed, it returns:
|
||||
// (true, parsed_spec, parsed_name)
|
||||
// (true, parsed_spec, locator, source, parsed_name)
|
||||
// If the input string didn't contain the string, it returns:
|
||||
// (false, DefaultSpec(), inputString)
|
||||
SpecFromString(inputString string) (bool, *api.VolumeSpec, string)
|
||||
// (false, DefaultSpec(), nil, nil, inputString)
|
||||
SpecFromString(inputString string) (
|
||||
bool,
|
||||
*api.VolumeSpec,
|
||||
*api.VolumeLocator,
|
||||
*api.Source,
|
||||
string,
|
||||
)
|
||||
|
||||
// SpecFromOpts parses in docker options passed in the the docker run
|
||||
// command of the form --opt name=value
|
||||
// source is populated if --opt parent=<volume_id> is specified.
|
||||
// If the options are validated then it returns:
|
||||
// (resultant_VolumeSpec, nil)
|
||||
// (resultant_VolumeSpec, source, locator, nil)
|
||||
// If the options have invalid values then it returns:
|
||||
// (nil, error)
|
||||
// (nil, nil, nil, error)
|
||||
|
||||
SpecFromOpts(opts map[string]string) (
|
||||
*api.VolumeSpec,
|
||||
*api.VolumeLocator,
|
||||
*api.Source,
|
||||
error,
|
||||
)
|
||||
|
||||
// UpdateSpecFromOpts parses in volume options passed through the opts map and updates given spec, locator & source
|
||||
// If the options are validated then it returns:
|
||||
// (resultant_VolumeSpec, source, locator, nil)
|
||||
// If the options have invalid values then it returns:
|
||||
// (nil, nil, nil, error)
|
||||
UpdateSpecFromOpts(opts map[string]string, spec *api.VolumeSpec, locator *api.VolumeLocator, source *api.Source) (
|
||||
*api.VolumeSpec,
|
||||
*api.VolumeLocator,
|
||||
*api.Source,
|
||||
error,
|
||||
)
|
||||
|
||||
SpecFromOpts(opts map[string]string) (*api.VolumeSpec, error)
|
||||
// Returns a default VolumeSpec if no docker options or string encoding
|
||||
// was provided.
|
||||
DefaultSpec() *api.VolumeSpec
|
||||
}
|
||||
|
||||
var (
|
||||
nameRegex = regexp.MustCompile(api.Name + "=([0-9A-Za-z]+),?")
|
||||
nameRegex = regexp.MustCompile(api.Name + "=([0-9A-Za-z_-]+),?")
|
||||
nodesRegex = regexp.MustCompile(api.SpecNodes + "=([0-9A-Za-z_-]+),?")
|
||||
sizeRegex = regexp.MustCompile(api.SpecSize + "=([0-9A-Za-z]+),?")
|
||||
scaleRegex = regexp.MustCompile(api.SpecScale + "=([0-9A-Za-z]+),?")
|
||||
scaleRegex = regexp.MustCompile(api.SpecScale + "=([0-9]+),?")
|
||||
fsRegex = regexp.MustCompile(api.SpecFilesystem + "=([0-9A-Za-z]+),?")
|
||||
bsRegex = regexp.MustCompile(api.SpecBlockSize + "=([0-9]+),?")
|
||||
haRegex = regexp.MustCompile(api.SpecHaLevel + "=([0-9]+),?")
|
||||
cosRegex = regexp.MustCompile(api.SpecPriority + "=([A-Za-z]+),?")
|
||||
sharedRegex = regexp.MustCompile(api.SpecShared + "=([A-Za-z]+),?")
|
||||
passphraseRegex = regexp.MustCompile(api.SpecPassphrase + "=([0-9A-Za-z_@./#&+-]+),?")
|
||||
stickyRegex = regexp.MustCompile(api.SpecSticky + "=([A-Za-z]+),?")
|
||||
secureRegex = regexp.MustCompile(api.SpecSecure + "=([A-Za-z]+),?")
|
||||
zonesRegex = regexp.MustCompile(api.SpecZones + "=([A-Za-z]+),?")
|
||||
racksRegex = regexp.MustCompile(api.SpecRacks + "=([A-Za-z]+),?")
|
||||
aggrRegex = regexp.MustCompile(api.SpecAggregationLevel + "=([0-9]+|" +
|
||||
api.SpecAutoAggregationValue + "),?")
|
||||
compressedRegex = regexp.MustCompile(api.SpecCompressed + "=([A-Za-z]+),?")
|
||||
snapScheduleRegex = regexp.MustCompile(api.SpecSnapshotSchedule +
|
||||
`=([A-Za-z0-9:;@=#]+),?`)
|
||||
)
|
||||
|
||||
type specHandler struct {
|
||||
}
|
||||
|
||||
// NewSpecHandler returns a new SpecHandler interface
|
||||
func NewSpecHandler() SpecHandler {
|
||||
return &specHandler{}
|
||||
}
|
||||
|
||||
func (d *specHandler) cosLevel(cos string) (uint32, error) {
|
||||
func (d *specHandler) cosLevel(cos string) (api.CosType, error) {
|
||||
cos = strings.ToLower(cos)
|
||||
switch cos {
|
||||
case "high", "3":
|
||||
return uint32(api.CosType_HIGH), nil
|
||||
return api.CosType_HIGH, nil
|
||||
case "medium", "2":
|
||||
return uint32(api.CosType_MEDIUM), nil
|
||||
return api.CosType_MEDIUM, nil
|
||||
case "low", "1", "":
|
||||
return uint32(api.CosType_LOW), nil
|
||||
return api.CosType_LOW, nil
|
||||
}
|
||||
return uint32(api.CosType_LOW),
|
||||
return api.CosType_NONE,
|
||||
fmt.Errorf("Cos must be one of %q | %q | %q", "high", "medium", "low")
|
||||
}
|
||||
|
||||
@@ -91,30 +131,58 @@ func (d *specHandler) DefaultSpec() *api.VolumeSpec {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *specHandler) SpecFromOpts(
|
||||
opts map[string]string,
|
||||
) (*api.VolumeSpec, error) {
|
||||
spec := d.DefaultSpec()
|
||||
func (d *specHandler) UpdateSpecFromOpts(opts map[string]string, spec *api.VolumeSpec, locator *api.VolumeLocator,
|
||||
source *api.Source) (*api.VolumeSpec, *api.VolumeLocator, *api.Source, error) {
|
||||
nodeList := make([]string, 0)
|
||||
|
||||
if spec == nil {
|
||||
spec = d.DefaultSpec()
|
||||
}
|
||||
|
||||
if source == nil {
|
||||
source = &api.Source{}
|
||||
}
|
||||
|
||||
if locator == nil {
|
||||
locator = &api.VolumeLocator{
|
||||
VolumeLabels: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range opts {
|
||||
switch k {
|
||||
case api.SpecNodes:
|
||||
inputNodes := strings.Split(v, ",")
|
||||
for _, node := range inputNodes {
|
||||
if len(node) != 0 {
|
||||
nodeList = append(nodeList, node)
|
||||
}
|
||||
}
|
||||
spec.ReplicaSet = &api.ReplicaSet{Nodes: nodeList}
|
||||
case api.SpecParent:
|
||||
source.Parent = v
|
||||
case api.SpecEphemeral:
|
||||
spec.Ephemeral, _ = strconv.ParseBool(v)
|
||||
case api.SpecSize:
|
||||
if size, err := units.Parse(v); err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.Size = uint64(size)
|
||||
}
|
||||
case api.SpecScale:
|
||||
if scale, err := strconv.ParseUint(v, 10, 64); err == nil {
|
||||
spec.Scale = uint32(scale)
|
||||
}
|
||||
|
||||
case api.SpecFilesystem:
|
||||
if value, err := api.FSTypeSimpleValueOf(v); err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.Format = value
|
||||
}
|
||||
case api.SpecBlockSize:
|
||||
if blockSize, err := units.Parse(v); err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.BlockSize = blockSize
|
||||
}
|
||||
@@ -122,39 +190,108 @@ func (d *specHandler) SpecFromOpts(
|
||||
haLevel, _ := strconv.ParseInt(v, 10, 64)
|
||||
spec.HaLevel = haLevel
|
||||
case api.SpecPriority:
|
||||
cos, _ := api.CosTypeSimpleValueOf(v)
|
||||
cos, err := d.cosLevel(v)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
spec.Cos = cos
|
||||
case api.SpecPriorityAlias:
|
||||
cos, err := d.cosLevel(v)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
spec.Cos = cos
|
||||
case api.SpecDedupe:
|
||||
spec.Dedupe, _ = strconv.ParseBool(v)
|
||||
case api.SpecSnapshotInterval:
|
||||
snapshotInterval, _ := strconv.ParseUint(v, 10, 32)
|
||||
spec.SnapshotInterval = uint32(snapshotInterval)
|
||||
case api.SpecSnapshotSchedule:
|
||||
spec.SnapshotSchedule = v
|
||||
case api.SpecAggregationLevel:
|
||||
aggregationLevel, _ := strconv.ParseUint(v, 10, 32)
|
||||
spec.AggregationLevel = uint32(aggregationLevel)
|
||||
if v == api.SpecAutoAggregationValue {
|
||||
spec.AggregationLevel = api.AutoAggregation
|
||||
} else {
|
||||
aggregationLevel, _ := strconv.ParseUint(v, 10, 32)
|
||||
spec.AggregationLevel = uint32(aggregationLevel)
|
||||
}
|
||||
case api.SpecShared:
|
||||
if shared, err := strconv.ParseBool(v); err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.Shared = shared
|
||||
}
|
||||
case api.SpecSticky:
|
||||
if sticky, err := strconv.ParseBool(v); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.Sticky = sticky
|
||||
}
|
||||
case api.SpecSecure:
|
||||
if secure, err := strconv.ParseBool(v); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.Encrypted = secure
|
||||
}
|
||||
case api.SpecPassphrase:
|
||||
spec.Encrypted = true
|
||||
spec.Passphrase = v
|
||||
case api.SpecGroup:
|
||||
spec.Group = &api.Group{Id: v}
|
||||
case api.SpecGroupEnforce:
|
||||
if groupEnforced, err := strconv.ParseBool(v); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.GroupEnforced = groupEnforced
|
||||
}
|
||||
case api.SpecZones, api.SpecRacks:
|
||||
locator.VolumeLabels[k] = v
|
||||
case api.SpecCompressed:
|
||||
if compressed, err := strconv.ParseBool(v); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.Compressed = compressed
|
||||
}
|
||||
case api.SpecLabels:
|
||||
if labels, err := parser.LabelsFromString(v); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
for k, v := range labels {
|
||||
locator.VolumeLabels[k] = v
|
||||
}
|
||||
}
|
||||
case api.SpecIoProfile:
|
||||
if ioProfile, err := api.IoProfileSimpleValueOf(v); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
spec.IoProfile = ioProfile
|
||||
}
|
||||
default:
|
||||
spec.VolumeLabels[k] = v
|
||||
}
|
||||
}
|
||||
return spec, nil
|
||||
return spec, locator, source, nil
|
||||
}
|
||||
|
||||
func (d *specHandler) SpecFromOpts(
|
||||
opts map[string]string,
|
||||
) (*api.VolumeSpec, *api.VolumeLocator, *api.Source, error) {
|
||||
source := &api.Source{}
|
||||
locator := &api.VolumeLocator{
|
||||
VolumeLabels: make(map[string]string),
|
||||
}
|
||||
|
||||
spec := d.DefaultSpec()
|
||||
return d.UpdateSpecFromOpts(opts, spec, locator, source)
|
||||
}
|
||||
|
||||
func (d *specHandler) SpecFromString(
|
||||
str string,
|
||||
) (bool, *api.VolumeSpec, string) {
|
||||
) (bool, *api.VolumeSpec, *api.VolumeLocator, *api.Source, string) {
|
||||
// If we can't parse the name, the rest of the spec is invalid.
|
||||
ok, name := d.getVal(nameRegex, str)
|
||||
if !ok {
|
||||
return false, d.DefaultSpec(), str
|
||||
return false, d.DefaultSpec(), nil, nil, str
|
||||
}
|
||||
|
||||
opts := make(map[string]string)
|
||||
@@ -162,6 +299,9 @@ func (d *specHandler) SpecFromString(
|
||||
if ok, sz := d.getVal(sizeRegex, str); ok {
|
||||
opts[api.SpecSize] = sz
|
||||
}
|
||||
if ok, nodes := d.getVal(nodesRegex, str); ok {
|
||||
opts[api.SpecNodes] = nodes
|
||||
}
|
||||
if ok, scale := d.getVal(scaleRegex, str); ok {
|
||||
opts[api.SpecScale] = scale
|
||||
}
|
||||
@@ -180,13 +320,34 @@ func (d *specHandler) SpecFromString(
|
||||
if ok, shared := d.getVal(sharedRegex, str); ok {
|
||||
opts[api.SpecShared] = shared
|
||||
}
|
||||
if ok, sticky := d.getVal(stickyRegex, str); ok {
|
||||
opts[api.SpecSticky] = sticky
|
||||
}
|
||||
if ok, secure := d.getVal(secureRegex, str); ok {
|
||||
opts[api.SpecSecure] = secure
|
||||
}
|
||||
if ok, passphrase := d.getVal(passphraseRegex, str); ok {
|
||||
opts[api.SpecPassphrase] = passphrase
|
||||
}
|
||||
|
||||
spec, err := d.SpecFromOpts(opts)
|
||||
if err != nil {
|
||||
return false, d.DefaultSpec(), name
|
||||
if ok, zones := d.getVal(zonesRegex, str); ok {
|
||||
opts[api.SpecZones] = zones
|
||||
}
|
||||
return true, spec, name
|
||||
if ok, racks := d.getVal(racksRegex, str); ok {
|
||||
opts[api.SpecRacks] = racks
|
||||
}
|
||||
if ok, aggregationLvl := d.getVal(aggrRegex, str); ok {
|
||||
opts[api.SpecAggregationLevel] = aggregationLvl
|
||||
}
|
||||
if ok, compressed := d.getVal(compressedRegex, str); ok {
|
||||
opts[api.SpecCompressed] = compressed
|
||||
}
|
||||
if ok, sched := d.getVal(snapScheduleRegex, str); ok {
|
||||
opts[api.SpecSnapshotSchedule] = strings.Replace(sched, "#", ",", -1)
|
||||
}
|
||||
|
||||
spec, locator, source, err := d.SpecFromOpts(opts)
|
||||
if err != nil {
|
||||
return false, d.DefaultSpec(), nil, nil, name
|
||||
}
|
||||
return true, spec, locator, source, name
|
||||
}
|
||||
|
30
vendor/github.com/libopenstorage/openstorage/api/status.go
generated
vendored
30
vendor/github.com/libopenstorage/openstorage/api/status.go
generated
vendored
@@ -1,5 +1,6 @@
|
||||
package api
|
||||
|
||||
// StatusKind indicates the severity of a status
|
||||
type StatusKind int32
|
||||
|
||||
const (
|
||||
@@ -12,32 +13,35 @@ const (
|
||||
)
|
||||
|
||||
var statusToStatusKind = map[Status]StatusKind{
|
||||
Status_STATUS_NONE: StatusSeverityHigh,
|
||||
Status_STATUS_INIT: StatusSeverityMedium,
|
||||
Status_STATUS_OK: StatusSeverityLow,
|
||||
Status_STATUS_OFFLINE: StatusSeverityHigh,
|
||||
Status_STATUS_ERROR: StatusSeverityHigh,
|
||||
Status_STATUS_NOT_IN_QUORUM: StatusSeverityHigh,
|
||||
Status_STATUS_DECOMMISSION: StatusSeverityHigh,
|
||||
Status_STATUS_MAINTENANCE: StatusSeverityHigh,
|
||||
Status_STATUS_STORAGE_DOWN: StatusSeverityHigh,
|
||||
Status_STATUS_STORAGE_DEGRADED: StatusSeverityHigh,
|
||||
Status_STATUS_NEEDS_REBOOT: StatusSeverityHigh,
|
||||
Status_STATUS_STORAGE_REBALANCE: StatusSeverityMedium,
|
||||
Status_STATUS_STORAGE_DRIVE_REPLACE: StatusSeverityMedium,
|
||||
Status_STATUS_NONE: StatusSeverityHigh,
|
||||
Status_STATUS_INIT: StatusSeverityMedium,
|
||||
Status_STATUS_OK: StatusSeverityLow,
|
||||
Status_STATUS_OFFLINE: StatusSeverityHigh,
|
||||
Status_STATUS_ERROR: StatusSeverityHigh,
|
||||
Status_STATUS_NOT_IN_QUORUM: StatusSeverityHigh,
|
||||
Status_STATUS_DECOMMISSION: StatusSeverityHigh,
|
||||
Status_STATUS_MAINTENANCE: StatusSeverityHigh,
|
||||
Status_STATUS_STORAGE_DOWN: StatusSeverityHigh,
|
||||
Status_STATUS_STORAGE_DEGRADED: StatusSeverityHigh,
|
||||
Status_STATUS_NEEDS_REBOOT: StatusSeverityHigh,
|
||||
Status_STATUS_STORAGE_REBALANCE: StatusSeverityMedium,
|
||||
Status_STATUS_STORAGE_DRIVE_REPLACE: StatusSeverityMedium,
|
||||
// Add statuses before MAX
|
||||
Status_STATUS_MAX: StatusSeverityHigh,
|
||||
}
|
||||
|
||||
// StatusSimpleValueOf returns the string format of Status
|
||||
func StatusSimpleValueOf(s string) (Status, error) {
|
||||
obj, err := simpleValueOf("status", Status_value, s)
|
||||
return Status(obj), err
|
||||
}
|
||||
|
||||
// SimpleString returns the string format of Status
|
||||
func (x Status) SimpleString() string {
|
||||
return simpleString("status", Status_name, int32(x))
|
||||
}
|
||||
|
||||
// StatusKind returns the king of status
|
||||
func (x Status) StatusKind() StatusKind {
|
||||
statusType, _ := statusToStatusKind[x]
|
||||
return statusType
|
||||
|
21
vendor/github.com/libopenstorage/openstorage/pkg/parser/BUILD
generated
vendored
Normal file
21
vendor/github.com/libopenstorage/openstorage/pkg/parser/BUILD
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["labels.go"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
74
vendor/github.com/libopenstorage/openstorage/pkg/parser/labels.go
generated
vendored
Normal file
74
vendor/github.com/libopenstorage/openstorage/pkg/parser/labels.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
NoLabel = "NoLabel"
|
||||
)
|
||||
|
||||
func LabelsFromString(str string) (map[string]string, error) {
|
||||
if len(str) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
labels := strings.Split(str, ",")
|
||||
m := make(map[string]string, len(labels))
|
||||
for _, v := range labels {
|
||||
if strings.Contains(v, "=") {
|
||||
label := strings.SplitN(v, "=", 2)
|
||||
if len(label) != 2 {
|
||||
return m, fmt.Errorf("Malformed label: %s", v)
|
||||
}
|
||||
if _, ok := m[label[0]]; ok {
|
||||
return m, fmt.Errorf("Duplicate label: %s", v)
|
||||
}
|
||||
m[label[0]] = label[1]
|
||||
} else if len(v) != 0 {
|
||||
m[v] = ""
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func LabelsToString(labels map[string]string) string {
|
||||
l := ""
|
||||
for k, v := range labels {
|
||||
if len(l) != 0 {
|
||||
l += ","
|
||||
}
|
||||
if len(v) != 0 {
|
||||
l += k + "=" + v
|
||||
} else if len(k) != 0 {
|
||||
l += k
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func MergeLabels(old map[string]string, new map[string]string) map[string]string {
|
||||
if old == nil {
|
||||
return new
|
||||
}
|
||||
if new == nil {
|
||||
return old
|
||||
}
|
||||
m := make(map[string]string, len(old)+len(new))
|
||||
for k, v := range old {
|
||||
m[k] = v
|
||||
}
|
||||
for k, v := range new {
|
||||
m[k] = v
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func HasLabels(set map[string]string, subset map[string]string) bool {
|
||||
for k, v1 := range subset {
|
||||
if v2, ok := set[k]; !ok || v1 != v2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
20
vendor/github.com/libopenstorage/openstorage/pkg/units/units.go
generated
vendored
20
vendor/github.com/libopenstorage/openstorage/pkg/units/units.go
generated
vendored
@@ -40,16 +40,16 @@ var (
|
||||
"B": 1,
|
||||
"b": 1,
|
||||
|
||||
"KB": KB,
|
||||
"kb": KB,
|
||||
"MB": MB,
|
||||
"mb": MB,
|
||||
"GB": GB,
|
||||
"gb": GB,
|
||||
"TB": TB,
|
||||
"tb": TB,
|
||||
"PB": PB,
|
||||
"pb": PB,
|
||||
"KB": KiB,
|
||||
"kb": KiB,
|
||||
"MB": MiB,
|
||||
"mb": MiB,
|
||||
"GB": GiB,
|
||||
"gb": GiB,
|
||||
"TB": TiB,
|
||||
"tb": TiB,
|
||||
"PB": PiB,
|
||||
"pb": PiB,
|
||||
|
||||
"K": KiB,
|
||||
"k": KiB,
|
||||
|
102
vendor/github.com/libopenstorage/openstorage/volume/volume.go
generated
vendored
102
vendor/github.com/libopenstorage/openstorage/volume/volume.go
generated
vendored
@@ -7,30 +7,67 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrAlreadyShutdown = errors.New("VolumeDriverProvider already shutdown")
|
||||
ErrExist = errors.New("Driver already exists")
|
||||
ErrDriverNotFound = errors.New("Driver implementation not found")
|
||||
ErrDriverInitializing = errors.New("Driver is initializing")
|
||||
ErrEnoEnt = errors.New("Volume does not exist.")
|
||||
ErrEnomem = errors.New("Out of memory.")
|
||||
ErrEinval = errors.New("Invalid argument")
|
||||
ErrVolDetached = errors.New("Volume is detached")
|
||||
ErrVolAttached = errors.New("Volume is attached")
|
||||
// ErrAlreadyShutdown returned when driver is shutdown
|
||||
ErrAlreadyShutdown = errors.New("VolumeDriverProvider already shutdown")
|
||||
// ErrExit returned when driver already registered
|
||||
ErrExist = errors.New("Already exists")
|
||||
// ErrDriverNotFound returned when a driver is not registered
|
||||
ErrDriverNotFound = errors.New("Driver implementation not found")
|
||||
// ErrDriverInitializing returned when a driver is initializing
|
||||
ErrDriverInitializing = errors.New("Driver is initializing")
|
||||
// ErrEnoEnt returned when volume does not exist
|
||||
ErrEnoEnt = errors.New("Volume does not exist.")
|
||||
// ErrEnomem returned when we are out of memory
|
||||
ErrEnomem = errors.New("Out of memory.")
|
||||
// ErrEinval returned when an invalid input is provided
|
||||
ErrEinval = errors.New("Invalid argument")
|
||||
// ErrVolDetached returned when volume is in detached state
|
||||
ErrVolDetached = errors.New("Volume is detached")
|
||||
// ErrVolAttached returned when volume is in attached state
|
||||
ErrVolAttached = errors.New("Volume is attached")
|
||||
// ErrVolAttachedOnRemoteNode returned when volume is in attached on different node
|
||||
ErrVolAttachedOnRemoteNode = errors.New("Volume is attached on another node")
|
||||
ErrVolAttachedScale = errors.New("Volume is attached but can be scaled")
|
||||
ErrVolHasSnaps = errors.New("Volume has snapshots associated")
|
||||
ErrNotSupported = errors.New("Operation not supported")
|
||||
// ErrVolAttachedScale returned when volume is attached and can be scaled
|
||||
ErrVolAttachedScale = errors.New("Volume is attached on another node." +
|
||||
" Increase scale factor to create more instances")
|
||||
// ErrVolHasSnaps returned when volume has previous snapshots
|
||||
ErrVolHasSnaps = errors.New("Volume has snapshots associated")
|
||||
// ErrNotSupported returned when the operation is not supported
|
||||
ErrNotSupported = errors.New("Operation not supported")
|
||||
// ErrVolBusy returned when volume is in busy state
|
||||
ErrVolBusy = errors.New("Volume is busy")
|
||||
)
|
||||
|
||||
// Constants used by the VolumeDriver
|
||||
const (
|
||||
APIVersion = "v1"
|
||||
// APIVersion for the volume management apis
|
||||
APIVersion = "v1"
|
||||
// PluginAPIBase where the docker unix socket resides
|
||||
PluginAPIBase = "/run/docker/plugins/"
|
||||
// DriverAPIBase where the osd unix socket resides
|
||||
DriverAPIBase = "/var/lib/osd/driver/"
|
||||
MountBase = "/var/lib/osd/mounts/"
|
||||
VolumeBase = "/var/lib/osd/"
|
||||
// MountBase for osd mountpoints
|
||||
MountBase = "/var/lib/osd/mounts/"
|
||||
// VolumeBase for osd volumes
|
||||
VolumeBase = "/var/lib/osd/"
|
||||
)
|
||||
|
||||
const (
|
||||
// LocationConstaint is a label that specifies data location constraint.
|
||||
LocationConstraint = "LocationConstraint"
|
||||
// LocalNode is an alias for this node - similar to localhost.
|
||||
LocalNode = "LocalNode"
|
||||
)
|
||||
|
||||
// AttachOptionsKey specifies a key type from a key-value pair
|
||||
// that will be passed in to the Attach api
|
||||
type AttachOptionsKey string
|
||||
|
||||
const (
|
||||
AttachOptionsSecret = AttachOptionsKey("SECRET_KEY")
|
||||
)
|
||||
|
||||
// Store defines the interface for basic volume store operations
|
||||
type Store interface {
|
||||
// Lock volume specified by volumeID.
|
||||
Lock(volumeID string) (interface{}, error)
|
||||
@@ -68,16 +105,34 @@ type IODriver interface {
|
||||
Flush(volumeID string) error
|
||||
}
|
||||
|
||||
// SnapshotDriver interfaces provides snapshot capability
|
||||
type SnapshotDriver interface {
|
||||
// Snapshot create volume snapshot.
|
||||
// Errors ErrEnoEnt may be returned
|
||||
Snapshot(volumeID string, readonly bool, locator *api.VolumeLocator) (string, error)
|
||||
// Restore restores volume to specified snapshot.
|
||||
Restore(volumeID string, snapshotID string) error
|
||||
}
|
||||
|
||||
// StatsDriver interface provides stats features
|
||||
type StatsDriver interface {
|
||||
// Stats for specified volume.
|
||||
// cumulative stats are /proc/diskstats style stats.
|
||||
// nonCumulative stats are stats for specific duration.
|
||||
// Errors ErrEnoEnt may be returned
|
||||
Stats(volumeID string, cumulative bool) (*api.Stats, error)
|
||||
// UsedSize returns currently used volume size.
|
||||
// Errors ErrEnoEnt may be returned.
|
||||
UsedSize(volumeID string) (uint64, error)
|
||||
// GetActiveRequests get active requests
|
||||
GetActiveRequests() (*api.ActiveRequests, error)
|
||||
}
|
||||
|
||||
// ProtoDriver must be implemented by all volume drivers. It specifies the
|
||||
// most basic functionality, such as creating and deleting volumes.
|
||||
type ProtoDriver interface {
|
||||
SnapshotDriver
|
||||
StatsDriver
|
||||
// Name returns the name of the driver.
|
||||
Name() string
|
||||
// Type of this driver
|
||||
@@ -99,16 +154,6 @@ type ProtoDriver interface {
|
||||
// Update not all fields of the spec are supported, ErrNotSupported will be thrown for unsupported
|
||||
// updates.
|
||||
Set(volumeID string, locator *api.VolumeLocator, spec *api.VolumeSpec) error
|
||||
// Stats for specified volume.
|
||||
// cumulative stats are /proc/diskstats style stats.
|
||||
// nonCumulative stats are stats for specific duration.
|
||||
// Errors ErrEnoEnt may be returned
|
||||
Stats(volumeID string, cumulative bool) (*api.Stats, error)
|
||||
// Alerts on this volume.
|
||||
// Errors ErrEnoEnt may be returned
|
||||
Alerts(volumeID string) (*api.Alerts, error)
|
||||
// GetActiveRequests get active requests
|
||||
GetActiveRequests() (*api.ActiveRequests, error)
|
||||
// Status returns a set of key-value pairs which give low
|
||||
// level diagnostic status about this driver.
|
||||
Status() [][2]string
|
||||
@@ -128,6 +173,7 @@ type Enumerator interface {
|
||||
SnapEnumerate(volID []string, snapLabels map[string]string) ([]*api.Volume, error)
|
||||
}
|
||||
|
||||
// StoreEnumerator combines Store and Enumerator capabilities
|
||||
type StoreEnumerator interface {
|
||||
Store
|
||||
Enumerator
|
||||
@@ -139,10 +185,10 @@ type BlockDriver interface {
|
||||
// Attach map device to the host.
|
||||
// On success the devicePath specifies location where the device is exported
|
||||
// Errors ErrEnoEnt, ErrVolAttached may be returned.
|
||||
Attach(volumeID string) (string, error)
|
||||
Attach(volumeID string, attachOptions map[string]string) (string, error)
|
||||
// Detach device from the host.
|
||||
// Errors ErrEnoEnt, ErrVolDetached may be returned.
|
||||
Detach(volumeID string) error
|
||||
Detach(volumeID string, unmountBeforeDetach bool) error
|
||||
}
|
||||
|
||||
// VolumeDriverProvider provides VolumeDrivers.
|
||||
@@ -165,7 +211,7 @@ type VolumeDriverRegistry interface {
|
||||
Add(name string, init func(map[string]string) (VolumeDriver, error)) error
|
||||
}
|
||||
|
||||
// VolumeDriverRegistry constructs a new VolumeDriverRegistry.
|
||||
// NewVolumeDriverRegistry constructs a new VolumeDriverRegistry.
|
||||
func NewVolumeDriverRegistry(nameToInitFunc map[string]func(map[string]string) (VolumeDriver, error)) VolumeDriverRegistry {
|
||||
return newVolumeDriverRegistry(nameToInitFunc)
|
||||
}
|
||||
|
39
vendor/github.com/libopenstorage/openstorage/volume/volume_not_supported.go
generated
vendored
39
vendor/github.com/libopenstorage/openstorage/volume/volume_not_supported.go
generated
vendored
@@ -8,19 +8,24 @@ var (
|
||||
// BlockNotSupported is a default (null) block driver implementation. This can be
|
||||
// used by drivers that do not want to (or care about) implementing the attach,
|
||||
// format and detach interfaces.
|
||||
BlockNotSupported = &blockNotSupported{}
|
||||
BlockNotSupported = &blockNotSupported{}
|
||||
// SnapshotNotSupported is a null snapshot driver implementation. This can be used
|
||||
// by drivers that do not want to implement the snapshot interface
|
||||
SnapshotNotSupported = &snapshotNotSupported{}
|
||||
IONotSupported = &ioNotSupported{}
|
||||
// IONotSupported is a null IODriver interface
|
||||
IONotSupported = &ioNotSupported{}
|
||||
// StatsNotSupported is a null stats driver implementation. This can be used
|
||||
// by drivers that do not want to implement the stats interface.
|
||||
StatsNotSupported = &statsNotSupported{}
|
||||
)
|
||||
|
||||
|
||||
type blockNotSupported struct{}
|
||||
|
||||
func (b *blockNotSupported) Attach(volumeID string) (string, error) {
|
||||
func (b *blockNotSupported) Attach(volumeID string, attachOptions map[string]string) (string, error) {
|
||||
return "", ErrNotSupported
|
||||
}
|
||||
|
||||
func (b *blockNotSupported) Detach(volumeID string) error {
|
||||
func (b *blockNotSupported) Detach(volumeID string, unmountBeforeDetach bool) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
@@ -30,6 +35,10 @@ func (s *snapshotNotSupported) Snapshot(volumeID string, readonly bool, locator
|
||||
return "", ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *snapshotNotSupported) Restore(volumeID, snapshotID string) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
type ioNotSupported struct{}
|
||||
|
||||
func (i *ioNotSupported) Read(volumeID string, buffer []byte, size uint64, offset int64) (int64, error) {
|
||||
@@ -43,3 +52,23 @@ func (i *ioNotSupported) Write(volumeID string, buffer []byte, size uint64, offs
|
||||
func (i *ioNotSupported) Flush(volumeID string) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
type statsNotSupported struct{}
|
||||
|
||||
// Stats returns stats
|
||||
func (s *statsNotSupported) Stats(
|
||||
volumeID string,
|
||||
cumulative bool,
|
||||
) (*api.Stats, error) {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// UsedSize returns allocated size
|
||||
func (s *statsNotSupported) UsedSize(volumeID string) (uint64, error) {
|
||||
return 0, ErrNotSupported
|
||||
}
|
||||
|
||||
// GetActiveRequests gets active requests
|
||||
func (s *statsNotSupported) GetActiveRequests() (*api.ActiveRequests, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
26
vendor/github.com/mohae/deepcopy/.gitignore
generated
vendored
Normal file
26
vendor/github.com/mohae/deepcopy/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*~
|
||||
*.out
|
||||
*.log
|
11
vendor/github.com/mohae/deepcopy/.travis.yml
generated
vendored
Normal file
11
vendor/github.com/mohae/deepcopy/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
script:
|
||||
- go test ./...
|
21
vendor/github.com/mohae/deepcopy/BUILD
generated
vendored
Normal file
21
vendor/github.com/mohae/deepcopy/BUILD
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["deepcopy.go"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
21
vendor/github.com/mohae/deepcopy/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mohae/deepcopy/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Joel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
8
vendor/github.com/mohae/deepcopy/README.md
generated
vendored
Normal file
8
vendor/github.com/mohae/deepcopy/README.md
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
deepCopy
|
||||
========
|
||||
[](https://godoc.org/github.com/mohae/deepcopy)[](https://travis-ci.org/mohae/deepcopy)
|
||||
|
||||
DeepCopy makes deep copies of things: unexported field values are not copied.
|
||||
|
||||
## Usage
|
||||
cpy := deepcopy.Copy(orig)
|
112
vendor/github.com/mohae/deepcopy/deepcopy.go
generated
vendored
Normal file
112
vendor/github.com/mohae/deepcopy/deepcopy.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
// deepcopy makes deep copies of things. A standard copy will copy the
|
||||
// pointers: deep copy copies the values pointed to. Unexported field
|
||||
// values are not copied.
|
||||
//
|
||||
// Copyright (c)2014-2016, Joel Scoble (github.com/mohae), all rights reserved.
|
||||
// License: MIT, for more details check the included LICENSE file.
|
||||
package deepcopy
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Iface is an alias to Copy; this exists for backwards compatibility reasons.
|
||||
func Iface(iface interface{}) interface{} {
|
||||
return Copy(iface)
|
||||
}
|
||||
|
||||
// Copy creates a deep copy of whatever is passed to it and returns the copy
|
||||
// in an interface{}. The returned value will need to be asserted to the
|
||||
// correct type.
|
||||
func Copy(src interface{}) interface{} {
|
||||
if src == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Make the interface a reflect.Value
|
||||
original := reflect.ValueOf(src)
|
||||
|
||||
// Make a copy of the same type as the original.
|
||||
cpy := reflect.New(original.Type()).Elem()
|
||||
|
||||
// Recursively copy the original.
|
||||
copyRecursive(original, cpy)
|
||||
|
||||
// Return the copy as an interface.
|
||||
return cpy.Interface()
|
||||
}
|
||||
|
||||
// copyRecursive does the actual copying of the interface. It currently has
|
||||
// limited support for what it can handle. Add as needed.
|
||||
func copyRecursive(original, cpy reflect.Value) {
|
||||
// handle according to original's Kind
|
||||
switch original.Kind() {
|
||||
case reflect.Ptr:
|
||||
// Get the actual value being pointed to.
|
||||
originalValue := original.Elem()
|
||||
|
||||
// if it isn't valid, return.
|
||||
if !originalValue.IsValid() {
|
||||
return
|
||||
}
|
||||
cpy.Set(reflect.New(originalValue.Type()))
|
||||
copyRecursive(originalValue, cpy.Elem())
|
||||
|
||||
case reflect.Interface:
|
||||
// If this is a nil, don't do anything
|
||||
if original.IsNil() {
|
||||
return
|
||||
}
|
||||
// Get the value for the interface, not the pointer.
|
||||
originalValue := original.Elem()
|
||||
|
||||
// Get the value by calling Elem().
|
||||
copyValue := reflect.New(originalValue.Type()).Elem()
|
||||
copyRecursive(originalValue, copyValue)
|
||||
cpy.Set(copyValue)
|
||||
|
||||
case reflect.Struct:
|
||||
t, ok := original.Interface().(time.Time)
|
||||
if ok {
|
||||
cpy.Set(reflect.ValueOf(t))
|
||||
return
|
||||
}
|
||||
// Go through each field of the struct and copy it.
|
||||
for i := 0; i < original.NumField(); i++ {
|
||||
// The Type's StructField for a given field is checked to see if StructField.PkgPath
|
||||
// is set to determine if the field is exported or not because CanSet() returns false
|
||||
// for settable fields. I'm not sure why. -mohae
|
||||
if original.Type().Field(i).PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
copyRecursive(original.Field(i), cpy.Field(i))
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
if original.IsNil() {
|
||||
return
|
||||
}
|
||||
// Make a new slice and copy each element.
|
||||
cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap()))
|
||||
for i := 0; i < original.Len(); i++ {
|
||||
copyRecursive(original.Index(i), cpy.Index(i))
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
if original.IsNil() {
|
||||
return
|
||||
}
|
||||
cpy.Set(reflect.MakeMap(original.Type()))
|
||||
for _, key := range original.MapKeys() {
|
||||
originalValue := original.MapIndex(key)
|
||||
copyValue := reflect.New(originalValue.Type()).Elem()
|
||||
copyRecursive(originalValue, copyValue)
|
||||
copyKey := Copy(key.Interface())
|
||||
cpy.SetMapIndex(reflect.ValueOf(copyKey), copyValue)
|
||||
}
|
||||
|
||||
default:
|
||||
cpy.Set(original)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user