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: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
Humble Chirammal 2018-04-18 11:15:33 +05:30
parent 2ef566d0c3
commit f7957e848b
2 changed files with 131 additions and 52 deletions

View File

@ -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
} }
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
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
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
} }
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
} }

View File

@ -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) {
&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) {
&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) {
&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) {
&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) {
&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) {
&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) {
&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) {
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 {