Commit f7957e84 authored by Humble Chirammal's avatar Humble Chirammal

This patch add a new parameter called `snapfactor` to glusterfs

storageclass. This is an optional parameter and value should fall into the range of 1-100. When set the thin pool calculation respect this snapfactor and create a thinpool accordingly. Signed-off-by: 's avatarHumble Chirammal <hchiramm@redhat.com>
parent 2ef566d0
...@@ -397,18 +397,19 @@ func (plugin *glusterfsPlugin) newProvisionerInternal(options volume.VolumeOptio ...@@ -397,18 +397,19 @@ func (plugin *glusterfsPlugin) newProvisionerInternal(options volume.VolumeOptio
} }
type provisionerConfig struct { type provisionerConfig struct {
url string url string
user string user string
userKey string userKey string
secretNamespace string secretNamespace string
secretName string secretName string
secretValue string secretValue string
clusterID string clusterID string
gidMin int gidMin int
gidMax int gidMax int
volumeType gapi.VolumeDurabilityInfo volumeType gapi.VolumeDurabilityInfo
volumeOptions []string volumeOptions []string
volumeNamePrefix string volumeNamePrefix string
thinPoolSnapFactor float32
} }
type glusterfsVolumeProvisioner struct { type glusterfsVolumeProvisioner struct {
...@@ -760,7 +761,15 @@ func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolum ...@@ -760,7 +761,15 @@ func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolum
} }
gid64 := int64(gid) gid64 := int64(gid)
volumeReq := &gapi.VolumeCreateRequest{Size: sz, Name: customVolumeName, Clusters: clusterIDs, Gid: gid64, Durability: p.volumeType, GlusterVolumeOptions: p.volumeOptions} snaps := struct {
Enable bool `json:"enable"`
Factor float32 `json:"factor"`
}{
true,
p.provisionerConfig.thinPoolSnapFactor,
}
volumeReq := &gapi.VolumeCreateRequest{Size: sz, Name: customVolumeName, Clusters: clusterIDs, Gid: gid64, Durability: p.volumeType, GlusterVolumeOptions: p.volumeOptions, Snapshot: snaps}
volume, err := cli.VolumeCreate(volumeReq) volume, err := cli.VolumeCreate(volumeReq)
if err != nil { if err != nil {
glog.Errorf("failed to create volume: %v", err) glog.Errorf("failed to create volume: %v", err)
...@@ -927,6 +936,10 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa ...@@ -927,6 +936,10 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa
parseVolumeType := "" parseVolumeType := ""
parseVolumeOptions := "" parseVolumeOptions := ""
parseVolumeNamePrefix := "" parseVolumeNamePrefix := ""
parseThinPoolSnapFactor := ""
//thin pool snap factor default to 1.0
cfg.thinPoolSnapFactor = float32(1.0)
for k, v := range params { for k, v := range params {
switch dstrings.ToLower(k) { switch dstrings.ToLower(k) {
...@@ -981,6 +994,11 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa ...@@ -981,6 +994,11 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa
if len(v) != 0 { if len(v) != 0 {
parseVolumeNamePrefix = v parseVolumeNamePrefix = v
} }
case "snapfactor":
if len(v) != 0 {
parseThinPoolSnapFactor = v
}
default: default:
return nil, fmt.Errorf("invalid option %q for volume plugin %s", k, glusterfsPluginName) return nil, fmt.Errorf("invalid option %q for volume plugin %s", k, glusterfsPluginName)
} }
...@@ -1068,6 +1086,17 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa ...@@ -1068,6 +1086,17 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa
} }
cfg.volumeNamePrefix = parseVolumeNamePrefix cfg.volumeNamePrefix = parseVolumeNamePrefix
} }
if len(parseThinPoolSnapFactor) != 0 {
thinPoolSnapFactor, err := strconv.ParseFloat(parseThinPoolSnapFactor, 32)
if err != nil {
return nil, fmt.Errorf("failed to convert snapfactor %v to float: %v", parseThinPoolSnapFactor, err)
}
if thinPoolSnapFactor < 1.0 || thinPoolSnapFactor > 100.0 {
return nil, fmt.Errorf("invalid snapshot factor %v, the value must be between 1 to 100", thinPoolSnapFactor)
}
cfg.thinPoolSnapFactor = float32(thinPoolSnapFactor)
}
return &cfg, nil return &cfg, nil
} }
......
...@@ -253,13 +253,14 @@ func TestParseClassParameters(t *testing.T) { ...@@ -253,13 +253,14 @@ func TestParseClassParameters(t *testing.T) {
nil, // secret nil, // secret
false, // expect error false, // expect error
&provisionerConfig{ &provisionerConfig{
url: "https://localhost:8080", url: "https://localhost:8080",
user: "admin", user: "admin",
userKey: "password", userKey: "password",
secretValue: "password", secretValue: "password",
gidMin: 2000, gidMin: 2000,
gidMax: 2147483647, gidMax: 2147483647,
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
thinPoolSnapFactor: float32(1.0),
}, },
}, },
{ {
...@@ -273,14 +274,15 @@ func TestParseClassParameters(t *testing.T) { ...@@ -273,14 +274,15 @@ func TestParseClassParameters(t *testing.T) {
&secret, &secret,
false, // expect error false, // expect error
&provisionerConfig{ &provisionerConfig{
url: "https://localhost:8080", url: "https://localhost:8080",
user: "admin", user: "admin",
secretName: "mysecret", secretName: "mysecret",
secretNamespace: "default", secretNamespace: "default",
secretValue: "mypassword", secretValue: "mypassword",
gidMin: 2000, gidMin: 2000,
gidMax: 2147483647, gidMax: 2147483647,
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
thinPoolSnapFactor: float32(1.0),
}, },
}, },
{ {
...@@ -292,10 +294,11 @@ func TestParseClassParameters(t *testing.T) { ...@@ -292,10 +294,11 @@ func TestParseClassParameters(t *testing.T) {
&secret, &secret,
false, // expect error false, // expect error
&provisionerConfig{ &provisionerConfig{
url: "https://localhost:8080", url: "https://localhost:8080",
gidMin: 2000, gidMin: 2000,
gidMax: 2147483647, gidMax: 2147483647,
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
thinPoolSnapFactor: float32(1.0),
}, },
}, },
{ {
...@@ -429,10 +432,11 @@ func TestParseClassParameters(t *testing.T) { ...@@ -429,10 +432,11 @@ func TestParseClassParameters(t *testing.T) {
&secret, &secret,
false, // expect error false, // expect error
&provisionerConfig{ &provisionerConfig{
url: "https://localhost:8080", url: "https://localhost:8080",
gidMin: 4000, gidMin: 4000,
gidMax: 2147483647, gidMax: 2147483647,
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
thinPoolSnapFactor: float32(1.0),
}, },
}, },
{ {
...@@ -445,10 +449,11 @@ func TestParseClassParameters(t *testing.T) { ...@@ -445,10 +449,11 @@ func TestParseClassParameters(t *testing.T) {
&secret, &secret,
false, // expect error false, // expect error
&provisionerConfig{ &provisionerConfig{
url: "https://localhost:8080", url: "https://localhost:8080",
gidMin: 2000, gidMin: 2000,
gidMax: 5000, gidMax: 5000,
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
thinPoolSnapFactor: float32(1.0),
}, },
}, },
{ {
...@@ -462,10 +467,11 @@ func TestParseClassParameters(t *testing.T) { ...@@ -462,10 +467,11 @@ func TestParseClassParameters(t *testing.T) {
&secret, &secret,
false, // expect error false, // expect error
&provisionerConfig{ &provisionerConfig{
url: "https://localhost:8080", url: "https://localhost:8080",
gidMin: 4000, gidMin: 4000,
gidMax: 5000, gidMax: 5000,
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
thinPoolSnapFactor: float32(1.0),
}, },
}, },
...@@ -481,10 +487,11 @@ func TestParseClassParameters(t *testing.T) { ...@@ -481,10 +487,11 @@ func TestParseClassParameters(t *testing.T) {
&secret, &secret,
false, // expect error false, // expect error
&provisionerConfig{ &provisionerConfig{
url: "https://localhost:8080", url: "https://localhost:8080",
gidMin: 4000, gidMin: 4000,
gidMax: 5000, gidMax: 5000,
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}}, volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
thinPoolSnapFactor: float32(1.0),
}, },
}, },
...@@ -500,10 +507,31 @@ func TestParseClassParameters(t *testing.T) { ...@@ -500,10 +507,31 @@ func TestParseClassParameters(t *testing.T) {
&secret, &secret,
false, // expect error false, // expect error
&provisionerConfig{ &provisionerConfig{
url: "https://localhost:8080", url: "https://localhost:8080",
gidMin: 4000, gidMin: 4000,
gidMax: 5000, gidMax: 5000,
volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}}, volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}},
thinPoolSnapFactor: float32(1.0),
},
},
{
"valid snapfactor: 50",
map[string]string{
"resturl": "https://localhost:8080",
"restauthenabled": "false",
"gidMin": "4000",
"gidMax": "5000",
"volumetype": "disperse:4:2",
"snapfactor": "50",
},
&secret,
false, // expect error
&provisionerConfig{
url: "https://localhost:8080",
gidMin: 4000,
gidMax: 5000,
volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}},
thinPoolSnapFactor: float32(50),
}, },
}, },
{ {
...@@ -550,6 +578,28 @@ func TestParseClassParameters(t *testing.T) { ...@@ -550,6 +578,28 @@ func TestParseClassParameters(t *testing.T) {
true, // expect error true, // expect error
nil, nil,
}, },
{
"invalid thinPoolSnapFactor: value out of range",
map[string]string{
"resturl": "https://localhost:8080",
"restauthenabled": "false",
"snapfactor": "0.5",
},
&secret,
true, // expect error
nil,
},
{
"invalid thinPoolSnapFactor: value out of range",
map[string]string{
"resturl": "https://localhost:8080",
"restauthenabled": "false",
"snapfactor": "120",
},
&secret,
true, // expect error
nil,
},
} }
for _, test := range tests { for _, test := range tests {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment