mirror of
https://github.com/TECHNOFAB11/zfs-localpv.git
synced 2025-12-11 22:10:11 +01:00
feat(zfspv) Add golint check to travis (#175)
Signed-off-by: vaniisgh <vanisingh@live.co.uk>
This commit is contained in:
parent
8b7ad5cb45
commit
8bbf3d7d2f
34 changed files with 321 additions and 266 deletions
|
|
@ -30,6 +30,7 @@ install:
|
||||||
fi
|
fi
|
||||||
- make bootstrap
|
- make bootstrap
|
||||||
- make format
|
- make format
|
||||||
|
- make golint
|
||||||
- curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.16.0/bin/linux/amd64/kubectl
|
- curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.16.0/bin/linux/amd64/kubectl
|
||||||
&& chmod +x kubectl && sudo mv kubectl /usr/local/bin/
|
&& chmod +x kubectl && sudo mv kubectl /usr/local/bin/
|
||||||
- curl -Lo minikube https://storage.googleapis.com/minikube/releases/v1.4.0/minikube-linux-amd64
|
- curl -Lo minikube https://storage.googleapis.com/minikube/releases/v1.4.0/minikube-linux-amd64
|
||||||
|
|
|
||||||
6
Makefile
6
Makefile
|
|
@ -25,7 +25,7 @@ VETARGS?=-asmdecl -atomic -bool -buildtags -copylocks -methods \
|
||||||
# targets or for development purposes
|
# targets or for development purposes
|
||||||
EXTERNAL_TOOLS=\
|
EXTERNAL_TOOLS=\
|
||||||
golang.org/x/tools/cmd/cover \
|
golang.org/x/tools/cmd/cover \
|
||||||
github.com/golang/lint/golint \
|
golang.org/x/lint/golint \
|
||||||
github.com/axw/gocov/gocov \
|
github.com/axw/gocov/gocov \
|
||||||
gopkg.in/matm/v1/gocov-html \
|
gopkg.in/matm/v1/gocov-html \
|
||||||
github.com/onsi/ginkgo/ginkgo \
|
github.com/onsi/ginkgo/ginkgo \
|
||||||
|
|
@ -242,7 +242,7 @@ deploy-images:
|
||||||
.PHONY: golint
|
.PHONY: golint
|
||||||
golint:
|
golint:
|
||||||
@echo "--> Running golint"
|
@echo "--> Running golint"
|
||||||
@echo "Consider these linter recommendations:"
|
@golint -set_exit_status $(PACKAGES)
|
||||||
@golint $(PACKAGES)
|
@echo "Completed golint no recommendations !!"
|
||||||
@echo "--------------------------------"
|
@echo "--------------------------------"
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
|
||||||
1
changelogs/unreleased/175-vaniisgh
Normal file
1
changelogs/unreleased/175-vaniisgh
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
add golint to travis & fix linting
|
||||||
|
|
@ -244,6 +244,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: VolStatus string that specifies the current state of the
|
||||||
|
volume provisioning request.
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
description: State specifies the current state of the volume provisioning
|
description: State specifies the current state of the volume provisioning
|
||||||
|
|
@ -417,6 +419,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: VolStatus string that specifies the current state of the
|
||||||
|
volume provisioning request.
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
description: State specifies the current state of the volume provisioning
|
description: State specifies the current state of the volume provisioning
|
||||||
|
|
@ -637,6 +641,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: SnapStatus string that reflects if the snapshot was cretaed
|
||||||
|
successfully
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -804,6 +810,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: SnapStatus string that reflects if the snapshot was cretaed
|
||||||
|
successfully
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
type: string
|
type: string
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: VolStatus string that specifies the current state of the
|
||||||
|
volume provisioning request.
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
description: State specifies the current state of the volume provisioning
|
description: State specifies the current state of the volume provisioning
|
||||||
|
|
@ -417,6 +419,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: VolStatus string that specifies the current state of the
|
||||||
|
volume provisioning request.
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
description: State specifies the current state of the volume provisioning
|
description: State specifies the current state of the volume provisioning
|
||||||
|
|
@ -637,6 +641,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: SnapStatus string that reflects if the snapshot was cretaed
|
||||||
|
successfully
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -804,6 +810,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: SnapStatus string that reflects if the snapshot was cretaed
|
||||||
|
successfully
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
type: string
|
type: string
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: SnapStatus string that reflects if the snapshot was cretaed
|
||||||
|
successfully
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -363,6 +365,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: SnapStatus string that reflects if the snapshot was cretaed
|
||||||
|
successfully
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
type: string
|
type: string
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: VolStatus string that specifies the current state of the
|
||||||
|
volume provisioning request.
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
description: State specifies the current state of the volume provisioning
|
description: State specifies the current state of the volume provisioning
|
||||||
|
|
@ -396,6 +398,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: VolStatus string that specifies the current state of the
|
||||||
|
volume provisioning request.
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
description: State specifies the current state of the volume provisioning
|
description: State specifies the current state of the volume provisioning
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: VolStatus string that specifies the current state of the
|
||||||
|
volume provisioning request.
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
description: State specifies the current state of the volume provisioning
|
description: State specifies the current state of the volume provisioning
|
||||||
|
|
@ -417,6 +419,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: VolStatus string that specifies the current state of the
|
||||||
|
volume provisioning request.
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
description: State specifies the current state of the volume provisioning
|
description: State specifies the current state of the volume provisioning
|
||||||
|
|
@ -637,6 +641,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: SnapStatus string that reflects if the snapshot was cretaed
|
||||||
|
successfully
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -804,6 +810,8 @@ spec:
|
||||||
- volumeType
|
- volumeType
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
description: SnapStatus string that reflects if the snapshot was cretaed
|
||||||
|
successfully
|
||||||
properties:
|
properties:
|
||||||
state:
|
state:
|
||||||
type: string
|
type: string
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,9 @@ type ZFSSnapshot struct {
|
||||||
Status SnapStatus `json:"status"`
|
Status SnapStatus `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZFSSnapshotList is a list of ZFSSnapshot resources
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
// +resource:path=zfssnapshots
|
// +resource:path=zfssnapshots
|
||||||
|
|
||||||
// ZFSSnapshotList is a list of ZFSSnapshot resources
|
|
||||||
type ZFSSnapshotList struct {
|
type ZFSSnapshotList struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ListMeta `json:"metadata"`
|
metav1.ListMeta `json:"metadata"`
|
||||||
|
|
@ -47,6 +46,7 @@ type ZFSSnapshotList struct {
|
||||||
Items []ZFSSnapshot `json:"items"`
|
Items []ZFSSnapshot `json:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SnapStatus string that reflects if the snapshot was cretaed successfully
|
||||||
type SnapStatus struct {
|
type SnapStatus struct {
|
||||||
State string `json:"state,omitempty"`
|
State string `json:"state,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,9 @@ type MountInfo struct {
|
||||||
MountOptions []string `json:"mountOptions"`
|
MountOptions []string `json:"mountOptions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZFSVolumeList is a list of ZFSVolume resources
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
// +resource:path=zfsvolumes
|
// +resource:path=zfsvolumes
|
||||||
|
|
||||||
// ZFSVolumeList is a list of ZFSVolume resources
|
|
||||||
type ZFSVolumeList struct {
|
type ZFSVolumeList struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ListMeta `json:"metadata"`
|
metav1.ListMeta `json:"metadata"`
|
||||||
|
|
@ -202,6 +201,7 @@ type VolumeInfo struct {
|
||||||
Shared string `json:"shared,omitempty"`
|
Shared string `json:"shared,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VolStatus string that specifies the current state of the volume provisioning request.
|
||||||
type VolStatus struct {
|
type VolStatus struct {
|
||||||
// State specifies the current state of the volume provisioning request.
|
// State specifies the current state of the volume provisioning request.
|
||||||
// The state "Pending" means that the volume creation request has not
|
// The state "Pending" means that the volume creation request has not
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,9 @@ type ZFSSnapshot struct {
|
||||||
Status SnapStatus `json:"status"`
|
Status SnapStatus `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZFSSnapshotList is a list of ZFSSnapshot resources
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
// +resource:path=zfssnapshots
|
// +resource:path=zfssnapshots
|
||||||
|
|
||||||
// ZFSSnapshotList is a list of ZFSSnapshot resources
|
|
||||||
type ZFSSnapshotList struct {
|
type ZFSSnapshotList struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ListMeta `json:"metadata"`
|
metav1.ListMeta `json:"metadata"`
|
||||||
|
|
@ -46,6 +45,7 @@ type ZFSSnapshotList struct {
|
||||||
Items []ZFSSnapshot `json:"items"`
|
Items []ZFSSnapshot `json:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SnapStatus string that reflects if the snapshot was cretaed successfully
|
||||||
type SnapStatus struct {
|
type SnapStatus struct {
|
||||||
State string `json:"state,omitempty"`
|
State string `json:"state,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,9 @@ type MountInfo struct {
|
||||||
MountOptions []string `json:"mountOptions"`
|
MountOptions []string `json:"mountOptions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZFSVolumeList is a list of ZFSVolume resources
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
// +resource:path=zfsvolumes
|
// +resource:path=zfsvolumes
|
||||||
|
|
||||||
// ZFSVolumeList is a list of ZFSVolume resources
|
|
||||||
type ZFSVolumeList struct {
|
type ZFSVolumeList struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ListMeta `json:"metadata"`
|
metav1.ListMeta `json:"metadata"`
|
||||||
|
|
@ -194,6 +193,7 @@ type VolumeInfo struct {
|
||||||
FsType string `json:"fsType,omitempty"`
|
FsType string `json:"fsType,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VolStatus string that specifies the current state of the volume provisioning request.
|
||||||
type VolStatus struct {
|
type VolStatus struct {
|
||||||
// State specifies the current state of the volume provisioning request.
|
// State specifies the current state of the volume provisioning request.
|
||||||
// The state "Pending" means that the volume creation request has not
|
// The state "Pending" means that the volume creation request has not
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,16 @@ type ClientsetGetter interface {
|
||||||
Get() (*kubernetes.Clientset, error)
|
Get() (*kubernetes.Clientset, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type clientset struct{}
|
// ClientsetStruct is used to export a kuberneter Clientset
|
||||||
|
type ClientsetStruct struct{}
|
||||||
|
|
||||||
// Clientset returns a pointer to clientset struct
|
// Clientset returns a pointer to clientset struct
|
||||||
func Clientset() *clientset {
|
func Clientset() *ClientsetStruct {
|
||||||
return &clientset{}
|
return &ClientsetStruct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a new instance of kubernetes clientset
|
// Get returns a new instance of kubernetes clientset
|
||||||
func (c *clientset) Get() (*kubernetes.Clientset, error) {
|
func (c *ClientsetStruct) Get() (*kubernetes.Clientset, error) {
|
||||||
config, err := Config().Get()
|
config, err := Config().Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get kubernetes clientset")
|
return nil, errors.Wrap(err, "failed to get kubernetes clientset")
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,11 @@ limitations under the License.
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConfigMapGetter abstracts fetching of ConfigMap instance from kubernetes
|
// ConfigMapGetter abstracts fetching of ConfigMap instance from kubernetes
|
||||||
|
|
@ -29,18 +30,19 @@ type ConfigMapGetter interface {
|
||||||
Get(options metav1.GetOptions) (*corev1.ConfigMap, error)
|
Get(options metav1.GetOptions) (*corev1.ConfigMap, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type configmap struct {
|
// Configmap is used to initialise a kubernetes Configmap struct
|
||||||
|
type Configmap struct {
|
||||||
namespace string // namespace where this configmap exists
|
namespace string // namespace where this configmap exists
|
||||||
name string // name of this configmap
|
name string // name of this configmap
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigMap returns a new instance of configmap
|
// ConfigMap returns a new instance of configmap
|
||||||
func ConfigMap(namespace, name string) *configmap {
|
func ConfigMap(namespace, name string) *Configmap {
|
||||||
return &configmap{namespace: namespace, name: name}
|
return &Configmap{namespace: namespace, name: name}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns configmap instance from kubernetes cluster
|
// Get returns configmap instance from kubernetes cluster
|
||||||
func (c *configmap) Get(options metav1.GetOptions) (cm *corev1.ConfigMap, err error) {
|
func (c *Configmap) Get(options metav1.GetOptions) (cm *corev1.ConfigMap, err error) {
|
||||||
if len(strings.TrimSpace(c.name)) == 0 {
|
if len(strings.TrimSpace(c.name)) == 0 {
|
||||||
return nil, errors.Errorf("missing config map name: failed to get config map from namespace %s", c.namespace)
|
return nil, errors.Errorf("missing config map name: failed to get config map from namespace %s", c.namespace)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,13 @@ limitations under the License.
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// test if configmap implements ConfigMapGetter interface
|
// test if configmap implements ConfigMapGetter interface
|
||||||
var _ ConfigMapGetter = &configmap{}
|
var _ ConfigMapGetter = &Configmap{}
|
||||||
|
|
||||||
func TestConfigMapGet(t *testing.T) {
|
func TestConfigMapGet(t *testing.T) {
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
|
|
|
||||||
|
|
@ -26,16 +26,17 @@ type DynamicProvider interface {
|
||||||
Provide() (k8sdynamic.Interface, error)
|
Provide() (k8sdynamic.Interface, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type dynamic struct{}
|
//DynamicStruct is used to initialise a kuberenets dynamic interface
|
||||||
|
type DynamicStruct struct{}
|
||||||
|
|
||||||
// Dynamic returns a new instance of dynamic
|
// Dynamic returns a new instance of dynamic
|
||||||
func Dynamic() *dynamic {
|
func Dynamic() *DynamicStruct {
|
||||||
return &dynamic{}
|
return &DynamicStruct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provide provides a kubernetes dynamic client capable of invoking operations
|
// Provide provides a kubernetes dynamic client capable of invoking operations
|
||||||
// against kubernetes resources
|
// against kubernetes resources
|
||||||
func (d *dynamic) Provide() (k8sdynamic.Interface, error) {
|
func (d *DynamicStruct) Provide() (k8sdynamic.Interface, error) {
|
||||||
config, err := Config().Get()
|
config, err := Config().Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to provide dynamic client")
|
return nil, errors.Wrap(err, "failed to provide dynamic client")
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// test if dynamic implements DynamicProvider interface
|
// test if dynamic implements DynamicProvider interface
|
||||||
var _ DynamicProvider = &dynamic{}
|
var _ DynamicProvider = &DynamicStruct{}
|
||||||
|
|
||||||
func TestDynamicProvider(t *testing.T) {
|
func TestDynamicProvider(t *testing.T) {
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,17 @@ type NamespaceGetter interface {
|
||||||
type NamespaceLister interface {
|
type NamespaceLister interface {
|
||||||
List(options metav1.ListOptions) (*corev1.NamespaceList, error)
|
List(options metav1.ListOptions) (*corev1.NamespaceList, error)
|
||||||
}
|
}
|
||||||
type namespace struct{}
|
|
||||||
|
// NamespaceStruct is used to initialise kubernetes namespace instnaces
|
||||||
|
type NamespaceStruct struct{}
|
||||||
|
|
||||||
// Namespace returns a pointer to the namespace struct
|
// Namespace returns a pointer to the namespace struct
|
||||||
func Namespace() *namespace {
|
func Namespace() *NamespaceStruct {
|
||||||
return &namespace{}
|
return &NamespaceStruct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a namespace instance from kubernetes cluster
|
// Get returns a namespace instance from kubernetes cluster
|
||||||
func (ns *namespace) Get(name string, options metav1.GetOptions) (*corev1.Namespace, error) {
|
func (ns *NamespaceStruct) Get(name string, options metav1.GetOptions) (*corev1.Namespace, error) {
|
||||||
cs, err := Clientset().Get()
|
cs, err := Clientset().Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get namespace: %s", name)
|
return nil, errors.Wrapf(err, "failed to get namespace: %s", name)
|
||||||
|
|
@ -48,7 +50,7 @@ func (ns *namespace) Get(name string, options metav1.GetOptions) (*corev1.Namesp
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a slice of namespaces defined in a Kubernetes cluster
|
// List returns a slice of namespaces defined in a Kubernetes cluster
|
||||||
func (ns *namespace) List(options metav1.ListOptions) (*corev1.NamespaceList, error) {
|
func (ns *NamespaceStruct) List(options metav1.ListOptions) (*corev1.NamespaceList, error) {
|
||||||
cs, err := Clientset().Get()
|
cs, err := Clientset().Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get namespaces")
|
return nil, errors.Wrapf(err, "failed to get namespaces")
|
||||||
|
|
|
||||||
|
|
@ -31,30 +31,31 @@ type NodeGetter interface {
|
||||||
type NodeLister interface {
|
type NodeLister interface {
|
||||||
List(options metav1.ListOptions) (*corev1.NodeList, error)
|
List(options metav1.ListOptions) (*corev1.NodeList, error)
|
||||||
}
|
}
|
||||||
type node struct{}
|
|
||||||
|
|
||||||
func Node() *node {
|
//NodeStruct returns a struct used to instantiate a kubernetes Node
|
||||||
return &node{}
|
type NodeStruct struct{}
|
||||||
|
|
||||||
|
// Node returnd a pointer to the node struct
|
||||||
|
func Node() *NodeStruct {
|
||||||
|
return &NodeStruct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a node instance from kubernetes cluster
|
// Get returns a node instance from kubernetes cluster
|
||||||
func (n *node) Get(name string, options metav1.GetOptions) (*corev1.Node, error) {
|
func (n *NodeStruct) Get(name string, options metav1.GetOptions) (*corev1.Node, error) {
|
||||||
cs, err := Clientset().Get()
|
cs, err := Clientset().Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get node: %s", name)
|
return nil, errors.Wrapf(err, "failed to get node: %s", name)
|
||||||
} else {
|
|
||||||
return cs.CoreV1().Nodes().Get(name, options)
|
|
||||||
}
|
}
|
||||||
|
return cs.CoreV1().Nodes().Get(name, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a slice of Nodes registered in a Kubernetes cluster
|
// List returns a slice of Nodes registered in a Kubernetes cluster
|
||||||
func (n *node) List(options metav1.ListOptions) (*corev1.NodeList, error) {
|
func (n *NodeStruct) List(options metav1.ListOptions) (*corev1.NodeList, error) {
|
||||||
cs, err := Clientset().Get()
|
cs, err := Clientset().Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get nodes")
|
return nil, errors.Wrapf(err, "failed to get nodes")
|
||||||
} else {
|
|
||||||
return cs.CoreV1().Nodes().List(options)
|
|
||||||
}
|
}
|
||||||
|
return cs.CoreV1().Nodes().List(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumberOfNodes returns the number of nodes registered in a Kubernetes cluster
|
// NumberOfNodes returns the number of nodes registered in a Kubernetes cluster
|
||||||
|
|
@ -63,9 +64,8 @@ func NumberOfNodes() (int, error) {
|
||||||
nodes, err := n.List(metav1.ListOptions{})
|
nodes, err := n.List(metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.Wrapf(err, "failed to get the number of nodes")
|
return 0, errors.Wrapf(err, "failed to get the number of nodes")
|
||||||
} else {
|
|
||||||
return len(nodes.Items), nil
|
|
||||||
}
|
}
|
||||||
|
return len(nodes.Items), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNode returns a node instance from kubernetes cluster
|
// GetNode returns a node instance from kubernetes cluster
|
||||||
|
|
@ -74,9 +74,8 @@ func GetNode(name string) (*corev1.Node, error) {
|
||||||
node, err := n.Get(name, metav1.GetOptions{})
|
node, err := n.Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get node")
|
return nil, errors.Wrapf(err, "failed to get node")
|
||||||
} else {
|
|
||||||
return node, nil
|
|
||||||
}
|
}
|
||||||
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListNodes returns list of node instance from kubernetes cluster
|
// ListNodes returns list of node instance from kubernetes cluster
|
||||||
|
|
@ -85,9 +84,8 @@ func ListNodes(options metav1.ListOptions) (*corev1.NodeList, error) {
|
||||||
nodelist, err := n.List(options)
|
nodelist, err := n.List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to list node")
|
return nil, errors.Wrapf(err, "failed to list node")
|
||||||
} else {
|
|
||||||
return nodelist, nil
|
|
||||||
}
|
}
|
||||||
|
return nodelist, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOSAndKernelVersion gets us the OS,Kernel version
|
// GetOSAndKernelVersion gets us the OS,Kernel version
|
||||||
|
|
|
||||||
|
|
@ -66,23 +66,24 @@ type ResourceDeleter interface {
|
||||||
Delete(obj *unstructured.Unstructured, subresources ...string) error
|
Delete(obj *unstructured.Unstructured, subresources ...string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type resource struct {
|
// ResourceStruct is used to abstract a kubernetes struct
|
||||||
|
type ResourceStruct struct {
|
||||||
gvr schema.GroupVersionResource // identify a resource
|
gvr schema.GroupVersionResource // identify a resource
|
||||||
namespace string // namespace where this resource is to be operated at
|
namespace string // namespace where this resource is to be operated at
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements Stringer interface
|
// String implements Stringer interface
|
||||||
func (r *resource) String() string {
|
func (r *ResourceStruct) String() string {
|
||||||
return r.gvr.String()
|
return r.gvr.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resource returns a new resource instance
|
// Resource returns a new resource instance
|
||||||
func Resource(gvr schema.GroupVersionResource, namespace string) *resource {
|
func Resource(gvr schema.GroupVersionResource, namespace string) *ResourceStruct {
|
||||||
return &resource{gvr: gvr, namespace: namespace}
|
return &ResourceStruct{gvr: gvr, namespace: namespace}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new resource in kubernetes cluster
|
// Create creates a new resource in kubernetes cluster
|
||||||
func (r *resource) Create(obj *unstructured.Unstructured, subresources ...string) (u *unstructured.Unstructured, err error) {
|
func (r *ResourceStruct) Create(obj *unstructured.Unstructured, subresources ...string) (u *unstructured.Unstructured, err error) {
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
err = errors.Errorf("nil resource instance: failed to create resource '%s' at '%s'", r.gvr, r.namespace)
|
err = errors.Errorf("nil resource instance: failed to create resource '%s' at '%s'", r.gvr, r.namespace)
|
||||||
return
|
return
|
||||||
|
|
@ -101,7 +102,7 @@ func (r *resource) Create(obj *unstructured.Unstructured, subresources ...string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes a existing resource in kubernetes cluster
|
// Delete deletes a existing resource in kubernetes cluster
|
||||||
func (r *resource) Delete(obj *unstructured.Unstructured, subresources ...string) error {
|
func (r *ResourceStruct) Delete(obj *unstructured.Unstructured, subresources ...string) error {
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
return errors.Errorf("nil resource instance: failed to delete resource '%s' at '%s'", r.gvr, r.namespace)
|
return errors.Errorf("nil resource instance: failed to delete resource '%s' at '%s'", r.gvr, r.namespace)
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +118,7 @@ func (r *resource) Delete(obj *unstructured.Unstructured, subresources ...string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a specific resource from kubernetes cluster
|
// Get returns a specific resource from kubernetes cluster
|
||||||
func (r *resource) Get(name string, opts metav1.GetOptions, subresources ...string) (u *unstructured.Unstructured, err error) {
|
func (r *ResourceStruct) Get(name string, opts metav1.GetOptions, subresources ...string) (u *unstructured.Unstructured, err error) {
|
||||||
if len(strings.TrimSpace(name)) == 0 {
|
if len(strings.TrimSpace(name)) == 0 {
|
||||||
err = errors.Errorf("missing resource name: failed to get resource '%s' at '%s'", r.gvr, r.namespace)
|
err = errors.Errorf("missing resource name: failed to get resource '%s' at '%s'", r.gvr, r.namespace)
|
||||||
return
|
return
|
||||||
|
|
@ -136,7 +137,7 @@ func (r *resource) Get(name string, opts metav1.GetOptions, subresources ...stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update updates the resource at kubernetes cluster
|
// Update updates the resource at kubernetes cluster
|
||||||
func (r *resource) Update(oldobj, newobj *unstructured.Unstructured, subresources ...string) (u *unstructured.Unstructured, err error) {
|
func (r *ResourceStruct) Update(oldobj, newobj *unstructured.Unstructured, subresources ...string) (u *unstructured.Unstructured, err error) {
|
||||||
if oldobj == nil {
|
if oldobj == nil {
|
||||||
err = errors.Errorf("nil old resource instance: failed to update resource '%s' at '%s'", r.gvr, r.namespace)
|
err = errors.Errorf("nil old resource instance: failed to update resource '%s' at '%s'", r.gvr, r.namespace)
|
||||||
return
|
return
|
||||||
|
|
@ -163,7 +164,7 @@ func (r *resource) Update(oldobj, newobj *unstructured.Unstructured, subresource
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a list of specific resource at kubernetes cluster
|
// List returns a list of specific resource at kubernetes cluster
|
||||||
func (r *resource) List(opts metav1.ListOptions) (u *unstructured.UnstructuredList, err error) {
|
func (r *ResourceStruct) List(opts metav1.ListOptions) (u *unstructured.UnstructuredList, err error) {
|
||||||
dynamic, err := Dynamic().Provide()
|
dynamic, err := Dynamic().Provide()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrapf(err, "failed to list resource '%s' at '%s'", r.gvr, r.namespace)
|
err = errors.Wrapf(err, "failed to list resource '%s' at '%s'", r.gvr, r.namespace)
|
||||||
|
|
@ -181,7 +182,7 @@ func (r *resource) List(opts metav1.ListOptions) (u *unstructured.UnstructuredLi
|
||||||
// create or update a given resource. It does so by implementing
|
// create or update a given resource. It does so by implementing
|
||||||
// ResourceApplier interface
|
// ResourceApplier interface
|
||||||
type ResourceCreateOrUpdater struct {
|
type ResourceCreateOrUpdater struct {
|
||||||
*resource
|
*ResourceStruct
|
||||||
|
|
||||||
// Various executors required to perform Apply
|
// Various executors required to perform Apply
|
||||||
// This is how this instance decouples its dependencies
|
// This is how this instance decouples its dependencies
|
||||||
|
|
@ -222,10 +223,10 @@ func NewResourceCreateOrUpdater(
|
||||||
) *ResourceCreateOrUpdater {
|
) *ResourceCreateOrUpdater {
|
||||||
resource := Resource(gvr, namespace)
|
resource := Resource(gvr, namespace)
|
||||||
t := &ResourceCreateOrUpdater{
|
t := &ResourceCreateOrUpdater{
|
||||||
resource: resource,
|
ResourceStruct: resource,
|
||||||
Getter: resource,
|
Getter: resource,
|
||||||
Creator: resource,
|
Creator: resource,
|
||||||
Updater: resource,
|
Updater: resource,
|
||||||
}
|
}
|
||||||
for _, o := range options {
|
for _, o := range options {
|
||||||
o(t)
|
o(t)
|
||||||
|
|
@ -235,10 +236,10 @@ func NewResourceCreateOrUpdater(
|
||||||
|
|
||||||
// String implements Stringer interface
|
// String implements Stringer interface
|
||||||
func (r *ResourceCreateOrUpdater) String() string {
|
func (r *ResourceCreateOrUpdater) String() string {
|
||||||
if r.resource == nil {
|
if r.ResourceStruct == nil {
|
||||||
return fmt.Sprint("ResourceCreateOrUpdater")
|
return fmt.Sprint("ResourceCreateOrUpdater")
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("ResourceCreateOrUpdater %s", r.resource)
|
return fmt.Sprintf("ResourceCreateOrUpdater %s", r.ResourceStruct)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply applies a resource to the kubernetes cluster. In other words, it
|
// Apply applies a resource to the kubernetes cluster. In other words, it
|
||||||
|
|
@ -285,7 +286,7 @@ type ResourceDeleteOptions struct {
|
||||||
|
|
||||||
// Delete is a resource that is suitable to be executed as a Delete operation
|
// Delete is a resource that is suitable to be executed as a Delete operation
|
||||||
type Delete struct {
|
type Delete struct {
|
||||||
*resource
|
*ResourceStruct
|
||||||
options ResourceDeleteOptions
|
options ResourceDeleteOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -293,7 +294,7 @@ type Delete struct {
|
||||||
func DeleteResource(gvr schema.GroupVersionResource, namespace string) *Delete {
|
func DeleteResource(gvr schema.GroupVersionResource, namespace string) *Delete {
|
||||||
resource := Resource(gvr, namespace)
|
resource := Resource(gvr, namespace)
|
||||||
options := ResourceDeleteOptions{Deleter: resource}
|
options := ResourceDeleteOptions{Deleter: resource}
|
||||||
return &Delete{resource: resource, options: options}
|
return &Delete{ResourceStruct: resource, options: options}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes a resource from a kubernetes cluster
|
// Delete deletes a resource from a kubernetes cluster
|
||||||
|
|
@ -313,7 +314,7 @@ type ResourceListOptions struct {
|
||||||
|
|
||||||
// List is a resource resource that is suitable to be executed as a List operation
|
// List is a resource resource that is suitable to be executed as a List operation
|
||||||
type List struct {
|
type List struct {
|
||||||
*resource
|
*ResourceStruct
|
||||||
options ResourceListOptions
|
options ResourceListOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -321,7 +322,7 @@ type List struct {
|
||||||
func ListResource(gvr schema.GroupVersionResource, namespace string) *List {
|
func ListResource(gvr schema.GroupVersionResource, namespace string) *List {
|
||||||
resource := Resource(gvr, namespace)
|
resource := Resource(gvr, namespace)
|
||||||
options := ResourceListOptions{Lister: resource}
|
options := ResourceListOptions{Lister: resource}
|
||||||
return &List{resource: resource, options: options}
|
return &List{ResourceStruct: resource, options: options}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List lists a resource from a kubernetes cluster
|
// List lists a resource from a kubernetes cluster
|
||||||
|
|
@ -340,7 +341,7 @@ type ResourceGetOptions struct {
|
||||||
|
|
||||||
// Get is resource that is suitable to be executed as Get operation
|
// Get is resource that is suitable to be executed as Get operation
|
||||||
type Get struct {
|
type Get struct {
|
||||||
*resource
|
*ResourceStruct
|
||||||
options ResourceGetOptions
|
options ResourceGetOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -348,7 +349,7 @@ type Get struct {
|
||||||
func GetResource(gvr schema.GroupVersionResource, namespace string) *Get {
|
func GetResource(gvr schema.GroupVersionResource, namespace string) *Get {
|
||||||
resource := Resource(gvr, namespace)
|
resource := Resource(gvr, namespace)
|
||||||
options := ResourceGetOptions{Getter: resource}
|
options := ResourceGetOptions{Getter: resource}
|
||||||
return &Get{resource: resource, options: options}
|
return &Get{ResourceStruct: resource, options: options}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get gets a resource from a kubernetes cluster
|
// Get gets a resource from a kubernetes cluster
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ limitations under the License.
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
// verify if resource struct is an implementation of ResourceGetter
|
// verify if resource struct is an implementation of ResourceGetter
|
||||||
var _ ResourceGetter = &resource{}
|
var _ ResourceGetter = &ResourceStruct{}
|
||||||
|
|
||||||
// verify if resource struct is an implementation of ResourceCreator
|
// verify if resource struct is an implementation of ResourceCreator
|
||||||
var _ ResourceCreator = &resource{}
|
var _ ResourceCreator = &ResourceStruct{}
|
||||||
|
|
||||||
// verify if resource struct is an implementation of ResourceUpdater
|
// verify if resource struct is an implementation of ResourceUpdater
|
||||||
var _ ResourceUpdater = &resource{}
|
var _ ResourceUpdater = &ResourceStruct{}
|
||||||
|
|
||||||
// verify if createOrUpdate struct is an implementation of ResourceApplier
|
// verify if createOrUpdate struct is an implementation of ResourceApplier
|
||||||
var _ ResourceApplier = &ResourceCreateOrUpdater{}
|
var _ ResourceApplier = &ResourceCreateOrUpdater{}
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Coerce the map's keys to lower case, which only works when unicode char is in
|
// GetCaseInsensitiveMap coercs the map's keys to lower case, which only works
|
||||||
// ASCII subset. May overwrite key-value pairs on different permutations of key
|
// when unicode char is in ASCII subset. May overwrite key-value pairs on
|
||||||
// case as in Key and key. DON'T force values to the lower case unconditionally,
|
// different permutations of key case as in Key and key. DON'T force values to the
|
||||||
// because values for keys such as mountpoint or keylocation are case-sensitive.
|
// lower case unconditionally, because values for keys such as mountpoint or
|
||||||
|
// keylocation are case-sensitive.
|
||||||
// Note that although keys such as 'comPREssion' are accepted and processed,
|
// Note that although keys such as 'comPREssion' are accepted and processed,
|
||||||
// even if they are technically invalid, updates to rectify such typing will be
|
// even if they are technically invalid, updates to rectify such typing will be
|
||||||
// prohibited as a forbidden update.
|
// prohibited as a forbidden update.
|
||||||
|
|
@ -36,7 +37,8 @@ func GetCaseInsensitiveMap(dict *map[string]string) map[string]string {
|
||||||
return insensitiveDict
|
return insensitiveDict
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case of GetCaseInsensitiveMap looking up one key-value pair only
|
// GetInsensitiveParameter handles special case ofGetCaseInsensitiveMap looking up one
|
||||||
|
// key-value pair only
|
||||||
func GetInsensitiveParameter(dict *map[string]string, key string) string {
|
func GetInsensitiveParameter(dict *map[string]string, key string) string {
|
||||||
insensitiveDict := GetCaseInsensitiveMap(dict)
|
insensitiveDict := GetCaseInsensitiveMap(dict)
|
||||||
return insensitiveDict[strings.ToLower(key)]
|
return insensitiveDict[strings.ToLower(key)]
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package usage
|
package usage
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -34,12 +35,14 @@ const (
|
||||||
|
|
||||||
// RunningStatus status is running
|
// RunningStatus status is running
|
||||||
RunningStatus string = "running"
|
RunningStatus string = "running"
|
||||||
// Event labels
|
// EventLabelNode holds the string label "nodes"
|
||||||
EventLabelNode string = "nodes"
|
EventLabelNode string = "nodes"
|
||||||
|
// EventLabelCapacity holds the string label "capacity"
|
||||||
EventLabelCapacity string = "capacity"
|
EventLabelCapacity string = "capacity"
|
||||||
|
|
||||||
// Replica Event replication
|
// Replica Event replication
|
||||||
Replica string = "replica:"
|
Replica string = "replica:"
|
||||||
|
// DefaultReplicaCount holds the replica count string
|
||||||
DefaultReplicaCount string = "replica:1"
|
DefaultReplicaCount string = "replica:1"
|
||||||
|
|
||||||
// DefaultCASType Event application name constant for volume event
|
// DefaultCASType Event application name constant for volume event
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@ var (
|
||||||
installerType = "OPENEBS_IO_INSTALLER_TYPE"
|
installerType = "OPENEBS_IO_INSTALLER_TYPE"
|
||||||
)
|
)
|
||||||
|
|
||||||
// versionSet is a struct which stores (sort of) fixed information about a
|
// VersionSet is a struct which stores (sort of) fixed information about a
|
||||||
// k8s environment
|
// k8s environment
|
||||||
type versionSet struct {
|
type VersionSet struct {
|
||||||
id string // OPENEBS_IO_USAGE_UUID
|
id string // OPENEBS_IO_USAGE_UUID
|
||||||
k8sVersion string // OPENEBS_IO_K8S_VERSION
|
k8sVersion string // OPENEBS_IO_K8S_VERSION
|
||||||
k8sArch string // OPENEBS_IO_K8S_ARCH
|
k8sArch string // OPENEBS_IO_K8S_ARCH
|
||||||
|
|
@ -45,13 +45,13 @@ type versionSet struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVersion returns a new versionSet struct
|
// NewVersion returns a new versionSet struct
|
||||||
func NewVersion() *versionSet {
|
func NewVersion() *VersionSet {
|
||||||
return &versionSet{}
|
return &VersionSet{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchAndSetVersion consumes the Kubernetes API to get environment constants
|
// fetchAndSetVersion consumes the Kubernetes API to get environment constants
|
||||||
// and returns a versionSet struct
|
// and returns a versionSet struct
|
||||||
func (v *versionSet) fetchAndSetVersion() error {
|
func (v *VersionSet) fetchAndSetVersion() error {
|
||||||
var err error
|
var err error
|
||||||
v.id, err = getUUIDbyNS("default")
|
v.id, err = getUUIDbyNS("default")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -79,7 +79,7 @@ func (v *versionSet) fetchAndSetVersion() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getVersion is a wrapper over fetchAndSetVersion
|
// getVersion is a wrapper over fetchAndSetVersion
|
||||||
func (v *versionSet) getVersion(override bool) error {
|
func (v *VersionSet) getVersion(override bool) error {
|
||||||
// If ENVs aren't set or the override is true, fetch the required
|
// If ENVs aren't set or the override is true, fetch the required
|
||||||
// values from the K8s APIserver
|
// values from the K8s APIserver
|
||||||
if _, present := env.Lookup(openEBSversion); !present || override {
|
if _, present := env.Lookup(openEBSversion); !present || override {
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@ limitations under the License.
|
||||||
package zfs
|
package zfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/klog"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
|
"k8s.io/klog"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -27,8 +28,8 @@ import (
|
||||||
* volume refers to the same block because of the way ZFS clone works, it will
|
* volume refers to the same block because of the way ZFS clone works, it will
|
||||||
* also have the same UUID.
|
* also have the same UUID.
|
||||||
*/
|
*/
|
||||||
func btrfsGenerateUuid(volume string) error {
|
func btrfsGenerateUUID(volume string) error {
|
||||||
device := ZFS_DEVPATH + volume
|
device := ZFSDevPath + volume
|
||||||
|
|
||||||
// for mounting the cloned volume for btrfs, a new UUID has to be generated
|
// for mounting the cloned volume for btrfs, a new UUID has to be generated
|
||||||
cmd := exec.Command("btrfstune", "-f", "-u", device)
|
cmd := exec.Command("btrfstune", "-f", "-u", device)
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@ func MountZvol(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
devicePath := ZFS_DEVPATH + volume
|
devicePath := ZFSDevPath + volume
|
||||||
|
|
||||||
err = FormatAndMountZvol(devicePath, mount)
|
err = FormatAndMountZvol(devicePath, mount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -244,7 +244,7 @@ func MountDataset(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
|
||||||
// MountFilesystem mounts the disk to the specified path
|
// MountFilesystem mounts the disk to the specified path
|
||||||
func MountFilesystem(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
|
func MountFilesystem(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
|
||||||
switch vol.Spec.VolumeType {
|
switch vol.Spec.VolumeType {
|
||||||
case VOLTYPE_DATASET:
|
case VolTypeDataset:
|
||||||
return MountDataset(vol, mount)
|
return MountDataset(vol, mount)
|
||||||
default:
|
default:
|
||||||
return MountZvol(vol, mount)
|
return MountZvol(vol, mount)
|
||||||
|
|
@ -254,7 +254,7 @@ func MountFilesystem(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
|
||||||
// MountBlock mounts the block disk to the specified path
|
// MountBlock mounts the block disk to the specified path
|
||||||
func MountBlock(vol *apis.ZFSVolume, mountinfo *apis.MountInfo) error {
|
func MountBlock(vol *apis.ZFSVolume, mountinfo *apis.MountInfo) error {
|
||||||
target := mountinfo.MountPath
|
target := mountinfo.MountPath
|
||||||
devicePath := ZFS_DEVPATH + vol.Spec.PoolName + "/" + vol.Name
|
devicePath := ZFSDevPath + vol.Spec.PoolName + "/" + vol.Name
|
||||||
mountopt := []string{"bind"}
|
mountopt := []string{"bind"}
|
||||||
|
|
||||||
mounter := &mount.SafeFormatAndMount{Interface: mount.New(""), Exec: mount.NewOsExec()}
|
mounter := &mount.SafeFormatAndMount{Interface: mount.New(""), Exec: mount.NewOsExec()}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func xfsTempMount(volume string) error {
|
func xfsTempMount(volume string) error {
|
||||||
device := ZFS_DEVPATH + volume
|
device := ZFSDevPath + volume
|
||||||
pvol := strings.Split(volume, "/")
|
pvol := strings.Split(volume, "/")
|
||||||
|
|
||||||
// create a temporary directory to mount the xfs file system
|
// create a temporary directory to mount the xfs file system
|
||||||
|
|
@ -70,8 +70,8 @@ func xfsTempMount(volume string) error {
|
||||||
* There might be something there in the xfs log, we have to clear them
|
* There might be something there in the xfs log, we have to clear them
|
||||||
* so that filesystem is clean and we can generate the UUID for it.
|
* so that filesystem is clean and we can generate the UUID for it.
|
||||||
*/
|
*/
|
||||||
func xfsGenerateUuid(volume string) error {
|
func xfsGenerateUUID(volume string) error {
|
||||||
device := ZFS_DEVPATH + volume
|
device := ZFSDevPath + volume
|
||||||
|
|
||||||
// temporary mount the volume with nouuid to replay the logs
|
// temporary mount the volume with nouuid to replay the logs
|
||||||
err := xfsTempMount(volume)
|
err := xfsTempMount(volume)
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ import (
|
||||||
|
|
||||||
// zfs related constants
|
// zfs related constants
|
||||||
const (
|
const (
|
||||||
ZFS_DEVPATH = "/dev/zvol/"
|
ZFSDevPath = "/dev/zvol/"
|
||||||
FSTYPE_ZFS = "zfs"
|
FSTypeZFS = "zfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// zfs command related constants
|
// zfs command related constants
|
||||||
|
|
@ -46,14 +46,14 @@ const (
|
||||||
|
|
||||||
// constants to define volume type
|
// constants to define volume type
|
||||||
const (
|
const (
|
||||||
VOLTYPE_DATASET = "DATASET"
|
VolTypeDataset = "DATASET"
|
||||||
VOLTYPE_ZVOL = "ZVOL"
|
VolTypeZVol = "ZVOL"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PropertyChanged return whether volume property is changed
|
// PropertyChanged return whether volume property is changed
|
||||||
func PropertyChanged(oldVol *apis.ZFSVolume, newVol *apis.ZFSVolume) bool {
|
func PropertyChanged(oldVol *apis.ZFSVolume, newVol *apis.ZFSVolume) bool {
|
||||||
if oldVol.Spec.VolumeType == VOLTYPE_DATASET &&
|
if oldVol.Spec.VolumeType == VolTypeDataset &&
|
||||||
newVol.Spec.VolumeType == VOLTYPE_DATASET &&
|
newVol.Spec.VolumeType == VolTypeDataset &&
|
||||||
oldVol.Spec.RecordSize != newVol.Spec.RecordSize {
|
oldVol.Spec.RecordSize != newVol.Spec.RecordSize {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -70,10 +70,10 @@ func GetVolumeType(fstype string) string {
|
||||||
* otherwise a zvol will be created
|
* otherwise a zvol will be created
|
||||||
*/
|
*/
|
||||||
switch fstype {
|
switch fstype {
|
||||||
case FSTYPE_ZFS:
|
case FSTypeZFS:
|
||||||
return VOLTYPE_DATASET
|
return VolTypeDataset
|
||||||
default:
|
default:
|
||||||
return VOLTYPE_ZVOL
|
return VolTypeZVol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,7 +129,7 @@ func buildCloneCreateArgs(vol *apis.ZFSVolume) []string {
|
||||||
|
|
||||||
ZFSVolArg = append(ZFSVolArg, ZFSCloneArg)
|
ZFSVolArg = append(ZFSVolArg, ZFSCloneArg)
|
||||||
|
|
||||||
if vol.Spec.VolumeType == VOLTYPE_DATASET {
|
if vol.Spec.VolumeType == VolTypeDataset {
|
||||||
if len(vol.Spec.Capacity) != 0 {
|
if len(vol.Spec.Capacity) != 0 {
|
||||||
quotaProperty := "quota=" + vol.Spec.Capacity
|
quotaProperty := "quota=" + vol.Spec.Capacity
|
||||||
ZFSVolArg = append(ZFSVolArg, "-o", quotaProperty)
|
ZFSVolArg = append(ZFSVolArg, "-o", quotaProperty)
|
||||||
|
|
@ -251,7 +251,7 @@ func buildVolumeSetArgs(vol *apis.ZFSVolume) []string {
|
||||||
|
|
||||||
ZFSVolArg = append(ZFSVolArg, ZFSSetArg)
|
ZFSVolArg = append(ZFSVolArg, ZFSSetArg)
|
||||||
|
|
||||||
if vol.Spec.VolumeType == VOLTYPE_DATASET &&
|
if vol.Spec.VolumeType == VolTypeDataset &&
|
||||||
len(vol.Spec.RecordSize) != 0 {
|
len(vol.Spec.RecordSize) != 0 {
|
||||||
recordsizeProperty := "recordsize=" + vol.Spec.RecordSize
|
recordsizeProperty := "recordsize=" + vol.Spec.RecordSize
|
||||||
ZFSVolArg = append(ZFSVolArg, recordsizeProperty)
|
ZFSVolArg = append(ZFSVolArg, recordsizeProperty)
|
||||||
|
|
@ -279,7 +279,7 @@ func buildVolumeResizeArgs(vol *apis.ZFSVolume) []string {
|
||||||
|
|
||||||
ZFSVolArg = append(ZFSVolArg, ZFSSetArg)
|
ZFSVolArg = append(ZFSVolArg, ZFSSetArg)
|
||||||
|
|
||||||
if vol.Spec.VolumeType == VOLTYPE_DATASET {
|
if vol.Spec.VolumeType == VolTypeDataset {
|
||||||
quotaProperty := "quota=" + vol.Spec.Capacity
|
quotaProperty := "quota=" + vol.Spec.Capacity
|
||||||
ZFSVolArg = append(ZFSVolArg, quotaProperty)
|
ZFSVolArg = append(ZFSVolArg, quotaProperty)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -320,7 +320,7 @@ func CreateVolume(vol *apis.ZFSVolume) error {
|
||||||
|
|
||||||
if err := getVolume(volume); err != nil {
|
if err := getVolume(volume); err != nil {
|
||||||
var args []string
|
var args []string
|
||||||
if vol.Spec.VolumeType == VOLTYPE_DATASET {
|
if vol.Spec.VolumeType == VolTypeDataset {
|
||||||
args = buildDatasetCreateArgs(vol)
|
args = buildDatasetCreateArgs(vol)
|
||||||
} else {
|
} else {
|
||||||
args = buildZvolCreateArgs(vol)
|
args = buildZvolCreateArgs(vol)
|
||||||
|
|
@ -365,10 +365,16 @@ func CreateClone(vol *apis.ZFSVolume) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if vol.Spec.FsType == "xfs" {
|
if vol.Spec.FsType == "xfs" {
|
||||||
return xfsGenerateUuid(volume)
|
return xfsGenerateUUID(volume)
|
||||||
}
|
}
|
||||||
if vol.Spec.FsType == "btrfs" {
|
if vol.Spec.FsType == "btrfs" {
|
||||||
return btrfsGenerateUuid(volume)
|
return btrfsGenerateUUID(volume)
|
||||||
|
}
|
||||||
|
if vol.Spec.FsType == "btrfs" {
|
||||||
|
return btrfsGenerateUUID(volume)
|
||||||
|
}
|
||||||
|
if vol.Spec.FsType == "btrfs" {
|
||||||
|
return btrfsGenerateUUID(volume)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -428,7 +434,7 @@ func MountZFSDataset(vol *apis.ZFSVolume, mountpath string) error {
|
||||||
|
|
||||||
// SetDatasetLegacyMount sets the dataset mountpoint to legacy if not set
|
// SetDatasetLegacyMount sets the dataset mountpoint to legacy if not set
|
||||||
func SetDatasetLegacyMount(vol *apis.ZFSVolume) error {
|
func SetDatasetLegacyMount(vol *apis.ZFSVolume) error {
|
||||||
if vol.Spec.VolumeType != VOLTYPE_DATASET {
|
if vol.Spec.VolumeType != VolTypeDataset {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -471,7 +477,7 @@ func SetVolumeProp(vol *apis.ZFSVolume) error {
|
||||||
|
|
||||||
if len(vol.Spec.Compression) == 0 &&
|
if len(vol.Spec.Compression) == 0 &&
|
||||||
len(vol.Spec.Dedup) == 0 &&
|
len(vol.Spec.Dedup) == 0 &&
|
||||||
(vol.Spec.VolumeType != VOLTYPE_DATASET ||
|
(vol.Spec.VolumeType != VolTypeDataset ||
|
||||||
len(vol.Spec.RecordSize) == 0) {
|
len(vol.Spec.RecordSize) == 0) {
|
||||||
//nothing to set, just return
|
//nothing to set, just return
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -587,11 +593,11 @@ func DestroySnapshot(snap *apis.ZFSSnapshot) error {
|
||||||
// GetVolumeDevPath returns devpath for the given volume
|
// GetVolumeDevPath returns devpath for the given volume
|
||||||
func GetVolumeDevPath(vol *apis.ZFSVolume) (string, error) {
|
func GetVolumeDevPath(vol *apis.ZFSVolume) (string, error) {
|
||||||
volume := vol.Spec.PoolName + "/" + vol.Name
|
volume := vol.Spec.PoolName + "/" + vol.Name
|
||||||
if vol.Spec.VolumeType == VOLTYPE_DATASET {
|
if vol.Spec.VolumeType == VolTypeDataset {
|
||||||
return volume, nil
|
return volume, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
devicePath := ZFS_DEVPATH + volume
|
devicePath := ZFSDevPath + volume
|
||||||
|
|
||||||
// evaluate the symlink to get the dev path for zvol
|
// evaluate the symlink to get the dev path for zvol
|
||||||
dev, err := filepath.EvalSymlinks(devicePath)
|
dev, err := filepath.EvalSymlinks(devicePath)
|
||||||
|
|
|
||||||
|
|
@ -21,20 +21,20 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListBuilder enables building an instance of
|
// ListBuilder enables building an instance of
|
||||||
// Podlist
|
// List
|
||||||
type ListBuilder struct {
|
type ListBuilder struct {
|
||||||
list *PodList
|
list *List
|
||||||
filters predicateList
|
filters predicateList
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewListBuilder returns a instance of ListBuilder
|
// NewListBuilder returns a instance of ListBuilder
|
||||||
func NewListBuilder() *ListBuilder {
|
func NewListBuilder() *ListBuilder {
|
||||||
return &ListBuilder{list: &PodList{items: []*Pod{}}}
|
return &ListBuilder{list: &List{items: []*Pod{}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListBuilderForAPIList returns a instance of ListBuilder from API PodList
|
// ListBuilderForAPIList returns a instance of ListBuilder from API List
|
||||||
func ListBuilderForAPIList(pods *corev1.PodList) *ListBuilder {
|
func ListBuilderForAPIList(pods *corev1.PodList) *ListBuilder {
|
||||||
b := &ListBuilder{list: &PodList{}}
|
b := &ListBuilder{list: &List{}}
|
||||||
if pods == nil {
|
if pods == nil {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +47,7 @@ func ListBuilderForAPIList(pods *corev1.PodList) *ListBuilder {
|
||||||
|
|
||||||
// ListBuilderForObjectList returns a instance of ListBuilder from API Pods
|
// ListBuilderForObjectList returns a instance of ListBuilder from API Pods
|
||||||
func ListBuilderForObjectList(pods ...*Pod) *ListBuilder {
|
func ListBuilderForObjectList(pods ...*Pod) *ListBuilder {
|
||||||
b := &ListBuilder{list: &PodList{}}
|
b := &ListBuilder{list: &List{}}
|
||||||
if pods == nil {
|
if pods == nil {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
@ -61,11 +61,11 @@ func ListBuilderForObjectList(pods ...*Pod) *ListBuilder {
|
||||||
// List returns the list of pod
|
// List returns the list of pod
|
||||||
// instances that was built by this
|
// instances that was built by this
|
||||||
// builder
|
// builder
|
||||||
func (b *ListBuilder) List() *PodList {
|
func (b *ListBuilder) List() *List {
|
||||||
if b.filters == nil || len(b.filters) == 0 {
|
if b.filters == nil || len(b.filters) == 0 {
|
||||||
return b.list
|
return b.list
|
||||||
}
|
}
|
||||||
filtered := &PodList{}
|
filtered := &List{}
|
||||||
for _, pod := range b.list.items {
|
for _, pod := range b.list.items {
|
||||||
if b.filters.all(pod) {
|
if b.filters.all(pod) {
|
||||||
filtered.items = append(filtered.items, pod)
|
filtered.items = append(filtered.items, pod)
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ type Pod struct {
|
||||||
object *corev1.Pod
|
object *corev1.Pod
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodList holds the list of API pod instances
|
// List holds the list of API pod instances
|
||||||
type PodList struct {
|
type List struct {
|
||||||
items []*Pod
|
items []*Pod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,8 +36,8 @@ type predicateList []Predicate
|
||||||
// against the provided pod instance
|
// against the provided pod instance
|
||||||
type Predicate func(*Pod) bool
|
type Predicate func(*Pod) bool
|
||||||
|
|
||||||
// ToAPIList converts PodList to API PodList
|
// ToAPIList converts List to API List
|
||||||
func (pl *PodList) ToAPIList() *corev1.PodList {
|
func (pl *List) ToAPIList() *corev1.PodList {
|
||||||
plist := &corev1.PodList{}
|
plist := &corev1.PodList{}
|
||||||
for _, pod := range pl.items {
|
for _, pod := range pl.items {
|
||||||
plist.Items = append(plist.Items, *pod.object)
|
plist.Items = append(plist.Items, *pod.object)
|
||||||
|
|
@ -56,8 +56,8 @@ func NewForAPIObject(obj *corev1.Pod, opts ...podBuildOption) *Pod {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the number of items present in the PodList
|
// Len returns the number of items present in the List
|
||||||
func (pl *PodList) Len() int {
|
func (pl *List) Len() int {
|
||||||
return len(pl.items)
|
return len(pl.items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ func IsCompleted() Predicate {
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasLabels returns true if provided labels
|
// HasLabels returns true if provided labels
|
||||||
// map[key]value are present in the provided PodList
|
// map[key]value are present in the provided List
|
||||||
// instance
|
// instance
|
||||||
func HasLabels(keyValuePair map[string]string) Predicate {
|
func HasLabels(keyValuePair map[string]string) Predicate {
|
||||||
return func(p *Pod) bool {
|
return func(p *Pod) bool {
|
||||||
|
|
@ -117,7 +117,7 @@ func HasLabels(keyValuePair map[string]string) Predicate {
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasLabel return true if provided lable
|
// HasLabel return true if provided lable
|
||||||
// key and value are present in the the provided PodList
|
// key and value are present in the the provided List
|
||||||
// instance
|
// instance
|
||||||
func (p *Pod) HasLabel(key, value string) bool {
|
func (p *Pod) HasLabel(key, value string) bool {
|
||||||
val, ok := p.object.GetLabels()[key]
|
val, ok := p.object.GetLabels()[key]
|
||||||
|
|
@ -154,15 +154,15 @@ func (p *Pod) GetAPIObject() *corev1.Pod {
|
||||||
return p.object
|
return p.object
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromList created a PodList with provided api podlist
|
// FromList created a List with provided api List
|
||||||
func FromList(pods *corev1.PodList) *PodList {
|
func FromList(pods *corev1.PodList) *List {
|
||||||
pl := ListBuilderForAPIList(pods).
|
pl := ListBuilderForAPIList(pods).
|
||||||
List()
|
List()
|
||||||
return pl
|
return pl
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScheduledNodes returns the nodes on which pods are scheduled
|
// GetScheduledNodes returns the nodes on which pods are scheduled
|
||||||
func (pl *PodList) GetScheduledNodes() map[string]int {
|
func (pl *List) GetScheduledNodes() map[string]int {
|
||||||
nodeNames := make(map[string]int)
|
nodeNames := make(map[string]int)
|
||||||
for _, p := range pl.items {
|
for _, p := range pl.items {
|
||||||
p := p // pin it
|
p := p // pin it
|
||||||
|
|
@ -171,8 +171,8 @@ func (pl *PodList) GetScheduledNodes() map[string]int {
|
||||||
return nodeNames
|
return nodeNames
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMatchNodeAny checks the PodList is running on the provided nodes
|
// IsMatchNodeAny checks the List is running on the provided nodes
|
||||||
func (pl *PodList) IsMatchNodeAny(nodes map[string]int) bool {
|
func (pl *List) IsMatchNodeAny(nodes map[string]int) bool {
|
||||||
for _, p := range pl.items {
|
for _, p := range pl.items {
|
||||||
p := p // pin it
|
p := p // pin it
|
||||||
if nodes[p.object.Spec.NodeName] == 0 {
|
if nodes[p.object.Spec.NodeName] == 0 {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListBuilder enables building an instance of
|
// ListBuilder enables building an instance of
|
||||||
// PVCList
|
// List
|
||||||
type ListBuilder struct {
|
type ListBuilder struct {
|
||||||
// template to build a list of pvcs
|
// template to build a list of pvcs
|
||||||
template *corev1.PersistentVolumeClaim
|
template *corev1.PersistentVolumeClaim
|
||||||
|
|
@ -32,14 +32,14 @@ type ListBuilder struct {
|
||||||
// template
|
// template
|
||||||
count int
|
count int
|
||||||
|
|
||||||
list *PVCList
|
list *List
|
||||||
filters PredicateList
|
filters PredicateList
|
||||||
errs []error
|
errs []error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewListBuilder returns an instance of ListBuilder
|
// NewListBuilder returns an instance of ListBuilder
|
||||||
func NewListBuilder() *ListBuilder {
|
func NewListBuilder() *ListBuilder {
|
||||||
return &ListBuilder{list: &PVCList{}}
|
return &ListBuilder{list: &List{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListBuilderFromTemplate returns a new instance of
|
// ListBuilderFromTemplate returns a new instance of
|
||||||
|
|
@ -62,7 +62,7 @@ func ListBuilderFromTemplate(pvc *corev1.PersistentVolumeClaim) *ListBuilder {
|
||||||
// ListBuilderForAPIObjects returns a new instance of
|
// ListBuilderForAPIObjects returns a new instance of
|
||||||
// ListBuilder based on provided api pvc list
|
// ListBuilder based on provided api pvc list
|
||||||
func ListBuilderForAPIObjects(pvcs *corev1.PersistentVolumeClaimList) *ListBuilder {
|
func ListBuilderForAPIObjects(pvcs *corev1.PersistentVolumeClaimList) *ListBuilder {
|
||||||
b := &ListBuilder{list: &PVCList{}}
|
b := &ListBuilder{list: &List{}}
|
||||||
|
|
||||||
if pvcs == nil {
|
if pvcs == nil {
|
||||||
b.errs = append(
|
b.errs = append(
|
||||||
|
|
@ -82,7 +82,7 @@ func ListBuilderForAPIObjects(pvcs *corev1.PersistentVolumeClaimList) *ListBuild
|
||||||
|
|
||||||
// ListBuilderForObjects returns a new instance of
|
// ListBuilderForObjects returns a new instance of
|
||||||
// ListBuilder based on provided pvc list
|
// ListBuilder based on provided pvc list
|
||||||
func ListBuilderForObjects(pvcs *PVCList) *ListBuilder {
|
func ListBuilderForObjects(pvcs *List) *ListBuilder {
|
||||||
b := &ListBuilder{}
|
b := &ListBuilder{}
|
||||||
if pvcs == nil {
|
if pvcs == nil {
|
||||||
b.errs = append(
|
b.errs = append(
|
||||||
|
|
@ -122,7 +122,7 @@ func (b *ListBuilder) buildFromTemplateIfNilList() {
|
||||||
|
|
||||||
// List returns the list of pvc instances
|
// List returns the list of pvc instances
|
||||||
// that was built by this builder
|
// that was built by this builder
|
||||||
func (b *ListBuilder) List() (*PVCList, error) {
|
func (b *ListBuilder) List() (*List, error) {
|
||||||
if len(b.errs) > 0 {
|
if len(b.errs) > 0 {
|
||||||
return nil, errors.Errorf("failed to build pvc list: %+v", b.errs)
|
return nil, errors.Errorf("failed to build pvc list: %+v", b.errs)
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,7 @@ func (b *ListBuilder) List() (*PVCList, error) {
|
||||||
return b.list, nil
|
return b.list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
filteredList := &PVCList{}
|
filteredList := &List{}
|
||||||
for _, pvc := range b.list.items {
|
for _, pvc := range b.list.items {
|
||||||
if b.filters.all(pvc) {
|
if b.filters.all(pvc) {
|
||||||
filteredList.items = append(filteredList.items, pvc)
|
filteredList.items = append(filteredList.items, pvc)
|
||||||
|
|
@ -144,7 +144,7 @@ func (b *ListBuilder) List() (*PVCList, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the number of items present
|
// Len returns the number of items present
|
||||||
// in the PVCList of a builder
|
// in the List of a builder
|
||||||
func (b *ListBuilder) Len() (int, error) {
|
func (b *ListBuilder) Len() (int, error) {
|
||||||
l, err := b.List()
|
l, err := b.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,21 @@ type PVC struct {
|
||||||
object *corev1.PersistentVolumeClaim
|
object *corev1.PersistentVolumeClaim
|
||||||
}
|
}
|
||||||
|
|
||||||
// PVCList is a wrapper over persistentvolumeclaim api
|
// List is a wrapper over persistentvolumeclaim api
|
||||||
// object. It provides build, validations and other common
|
// object. It provides build, validations and other common
|
||||||
// logic to be used by various feature specific callers.
|
// logic to be used by various feature specific callers.
|
||||||
type PVCList struct {
|
type List struct {
|
||||||
items []*PVC
|
items []*PVC
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the number of items present
|
// Len returns the number of items present
|
||||||
// in the PVCList
|
// in the List
|
||||||
func (p *PVCList) Len() int {
|
func (p *List) Len() int {
|
||||||
return len(p.items)
|
return len(p.items)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToAPIList converts PVCList to API PVCList
|
// ToAPIList converts List to API List
|
||||||
func (p *PVCList) ToAPIList() *corev1.PersistentVolumeClaimList {
|
func (p *List) ToAPIList() *corev1.PersistentVolumeClaimList {
|
||||||
plist := &corev1.PersistentVolumeClaimList{}
|
plist := &corev1.PersistentVolumeClaimList{}
|
||||||
for _, pvc := range p.items {
|
for _, pvc := range p.items {
|
||||||
plist.Items = append(plist.Items, *pvc.object)
|
plist.Items = append(plist.Items, *pvc.object)
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ func (b *ListBuilder) APIList() (*storagev1.StorageClassList, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the number of items present
|
// Len returns the number of items present
|
||||||
// in the PVCList of a builder
|
// in the List of a builder
|
||||||
func (b *ListBuilder) Len() (int, error) {
|
func (b *ListBuilder) Len() (int, error) {
|
||||||
l, err := b.List()
|
l, err := b.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
235
tests/utils.go
235
tests/utils.go
|
|
@ -19,8 +19,9 @@ package tests
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
|
|
||||||
apis "github.com/openebs/zfs-localpv/pkg/apis/openebs.io/zfs/v1"
|
apis "github.com/openebs/zfs-localpv/pkg/apis/openebs.io/zfs/v1"
|
||||||
"github.com/openebs/zfs-localpv/pkg/zfs"
|
"github.com/openebs/zfs-localpv/pkg/zfs"
|
||||||
"github.com/openebs/zfs-localpv/tests/container"
|
"github.com/openebs/zfs-localpv/tests/container"
|
||||||
|
|
@ -39,14 +40,14 @@ import (
|
||||||
|
|
||||||
// IsPVCBoundEventually checks if the pvc is bound or not eventually
|
// IsPVCBoundEventually checks if the pvc is bound or not eventually
|
||||||
func IsPVCBoundEventually(pvcName string) bool {
|
func IsPVCBoundEventually(pvcName string) bool {
|
||||||
return Eventually(func() bool {
|
return gomega.Eventually(func() bool {
|
||||||
volume, err := PVCClient.
|
volume, err := PVCClient.
|
||||||
Get(pvcName, metav1.GetOptions{})
|
Get(pvcName, metav1.GetOptions{})
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||||
return pvc.NewForAPIObject(volume).IsBound()
|
return pvc.NewForAPIObject(volume).IsBound()
|
||||||
},
|
},
|
||||||
60, 5).
|
60, 5).
|
||||||
Should(BeTrue())
|
Should(gomega.BeTrue())
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPVCResizedEventually checks if the pvc is bound or not eventually
|
// IsPVCResizedEventually checks if the pvc is bound or not eventually
|
||||||
|
|
@ -55,54 +56,54 @@ func IsPVCResizedEventually(pvcName string, newCapacity string) bool {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return Eventually(func() bool {
|
return gomega.Eventually(func() bool {
|
||||||
volume, err := PVCClient.
|
volume, err := PVCClient.
|
||||||
Get(pvcName, metav1.GetOptions{})
|
Get(pvcName, metav1.GetOptions{})
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||||
pvcStorage := volume.Status.Capacity[corev1.ResourceName(corev1.ResourceStorage)]
|
pvcStorage := volume.Status.Capacity[corev1.ResourceName(corev1.ResourceStorage)]
|
||||||
return pvcStorage == newStorage
|
return pvcStorage == newStorage
|
||||||
},
|
},
|
||||||
120, 5).
|
120, 5).
|
||||||
Should(BeTrue())
|
Should(gomega.BeTrue())
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPodRunningEventually return true if the pod comes to running state
|
// IsPodRunningEventually return true if the pod comes to running state
|
||||||
func IsPodRunningEventually(namespace, podName string) bool {
|
func IsPodRunningEventually(namespace, podName string) bool {
|
||||||
return Eventually(func() bool {
|
return gomega.Eventually(func() bool {
|
||||||
p, err := PodClient.
|
p, err := PodClient.
|
||||||
WithNamespace(namespace).
|
WithNamespace(namespace).
|
||||||
Get(podName, metav1.GetOptions{})
|
Get(podName, metav1.GetOptions{})
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||||
return pod.NewForAPIObject(p).
|
return pod.NewForAPIObject(p).
|
||||||
IsRunning()
|
IsRunning()
|
||||||
},
|
},
|
||||||
60, 5).
|
60, 5).
|
||||||
Should(BeTrue())
|
Should(gomega.BeTrue())
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPropUpdatedEventually checks if the property is updated or not eventually
|
// IsPropUpdatedEventually checks if the property is updated or not eventually
|
||||||
func IsPropUpdatedEventually(vol *apis.ZFSVolume, prop string, val string) bool {
|
func IsPropUpdatedEventually(vol *apis.ZFSVolume, prop string, val string) bool {
|
||||||
return Eventually(func() bool {
|
return gomega.Eventually(func() bool {
|
||||||
|
|
||||||
newVal, err := zfs.GetVolumeProperty(vol, prop)
|
newVal, err := zfs.GetVolumeProperty(vol, prop)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||||
return (newVal == val)
|
return (newVal == val)
|
||||||
},
|
},
|
||||||
60, 5).
|
60, 5).
|
||||||
Should(BeTrue())
|
Should(gomega.BeTrue())
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPVCDeletedEventually tries to get the deleted pvc
|
// IsPVCDeletedEventually tries to get the deleted pvc
|
||||||
// and returns true if pvc is not found
|
// and returns true if pvc is not found
|
||||||
// else returns false
|
// else returns false
|
||||||
func IsPVCDeletedEventually(pvcName string) bool {
|
func IsPVCDeletedEventually(pvcName string) bool {
|
||||||
return Eventually(func() bool {
|
return gomega.Eventually(func() bool {
|
||||||
_, err := PVCClient.
|
_, err := PVCClient.
|
||||||
Get(pvcName, metav1.GetOptions{})
|
Get(pvcName, metav1.GetOptions{})
|
||||||
return k8serrors.IsNotFound(err)
|
return k8serrors.IsNotFound(err)
|
||||||
},
|
},
|
||||||
120, 10).
|
120, 10).
|
||||||
Should(BeTrue())
|
Should(gomega.BeTrue())
|
||||||
}
|
}
|
||||||
|
|
||||||
func createExt4StorageClass() {
|
func createExt4StorageClass() {
|
||||||
|
|
@ -115,16 +116,16 @@ func createExt4StorageClass() {
|
||||||
"fstype": "ext4",
|
"fstype": "ext4",
|
||||||
}
|
}
|
||||||
|
|
||||||
By("building a ext4 storage class")
|
ginkgo.By("building a ext4 storage class")
|
||||||
scObj, err = sc.NewBuilder().
|
scObj, err = sc.NewBuilder().
|
||||||
WithGenerateName(scName).
|
WithGenerateName(scName).
|
||||||
WithParametersNew(parameters).
|
WithParametersNew(parameters).
|
||||||
WithProvisioner(ZFSProvisioner).Build()
|
WithProvisioner(ZFSProvisioner).Build()
|
||||||
Expect(err).ShouldNot(HaveOccurred(),
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred(),
|
||||||
"while building ext4 storageclass obj with prefix {%s}", scName)
|
"while building ext4 storageclass obj with prefix {%s}", scName)
|
||||||
|
|
||||||
scObj, err = SCClient.Create(scObj)
|
scObj, err = SCClient.Create(scObj)
|
||||||
Expect(err).To(BeNil(), "while creating a ext4 storageclass {%s}", scName)
|
gomega.Expect(err).To(gomega.BeNil(), "while creating a ext4 storageclass {%s}", scName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createStorageClass() {
|
func createStorageClass() {
|
||||||
|
|
@ -136,16 +137,16 @@ func createStorageClass() {
|
||||||
"poolname": POOLNAME,
|
"poolname": POOLNAME,
|
||||||
}
|
}
|
||||||
|
|
||||||
By("building a default storage class")
|
ginkgo.By("building a default storage class")
|
||||||
scObj, err = sc.NewBuilder().
|
scObj, err = sc.NewBuilder().
|
||||||
WithGenerateName(scName).
|
WithGenerateName(scName).
|
||||||
WithParametersNew(parameters).
|
WithParametersNew(parameters).
|
||||||
WithProvisioner(ZFSProvisioner).Build()
|
WithProvisioner(ZFSProvisioner).Build()
|
||||||
Expect(err).ShouldNot(HaveOccurred(),
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred(),
|
||||||
"while building default storageclass obj with prefix {%s}", scName)
|
"while building default storageclass obj with prefix {%s}", scName)
|
||||||
|
|
||||||
scObj, err = SCClient.Create(scObj)
|
scObj, err = SCClient.Create(scObj)
|
||||||
Expect(err).To(BeNil(), "while creating a default storageclass {%s}", scName)
|
gomega.Expect(err).To(gomega.BeNil(), "while creating a default storageclass {%s}", scName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createZfsStorageClass() {
|
func createZfsStorageClass() {
|
||||||
|
|
@ -158,145 +159,147 @@ func createZfsStorageClass() {
|
||||||
"fstype": "zfs",
|
"fstype": "zfs",
|
||||||
}
|
}
|
||||||
|
|
||||||
By("building a zfs storage class")
|
ginkgo.By("building a zfs storage class")
|
||||||
scObj, err = sc.NewBuilder().
|
scObj, err = sc.NewBuilder().
|
||||||
WithGenerateName(scName).
|
WithGenerateName(scName).
|
||||||
WithParametersNew(parameters).
|
WithParametersNew(parameters).
|
||||||
WithVolumeExpansion(true).
|
WithVolumeExpansion(true).
|
||||||
WithProvisioner(ZFSProvisioner).Build()
|
WithProvisioner(ZFSProvisioner).Build()
|
||||||
Expect(err).ShouldNot(HaveOccurred(),
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred(),
|
||||||
"while building zfs storageclass obj with prefix {%s}", scName)
|
"while building zfs storageclass obj with prefix {%s}", scName)
|
||||||
|
|
||||||
scObj, err = SCClient.Create(scObj)
|
scObj, err = SCClient.Create(scObj)
|
||||||
Expect(err).To(BeNil(), "while creating a zfs storageclass {%s}", scName)
|
gomega.Expect(err).To(gomega.BeNil(), "while creating a zfs storageclass {%s}", scName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VerifyZFSVolume verify the properties of a zfs-volume
|
||||||
func VerifyZFSVolume() {
|
func VerifyZFSVolume() {
|
||||||
By("fetching zfs volume")
|
ginkgo.By("fetching zfs volume")
|
||||||
vol, err := ZFSClient.WithNamespace(OpenEBSNamespace).
|
vol, err := ZFSClient.WithNamespace(OpenEBSNamespace).
|
||||||
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
||||||
Expect(err).To(BeNil(), "while fetching the zfs volume {%s}", pvcObj.Spec.VolumeName)
|
gomega.Expect(err).To(gomega.BeNil(), "while fetching the zfs volume {%s}", pvcObj.Spec.VolumeName)
|
||||||
|
|
||||||
volType := zfs.VOLTYPE_ZVOL
|
volType := zfs.VolTypeZVol
|
||||||
if scObj.Parameters["fstype"] == zfs.FSTYPE_ZFS {
|
if scObj.Parameters["fstype"] == zfs.FSTypeZFS {
|
||||||
volType = zfs.VOLTYPE_DATASET
|
volType = zfs.VolTypeDataset
|
||||||
}
|
}
|
||||||
|
|
||||||
By("verifying zfs volume")
|
ginkgo.By("verifying zfs volume")
|
||||||
Expect(vol.Spec.PoolName).To(Equal(scObj.Parameters["poolname"]),
|
gomega.Expect(vol.Spec.PoolName).To(gomega.Equal(scObj.Parameters["poolname"]),
|
||||||
"while checking poolname of zfs volume", pvcObj.Spec.VolumeName)
|
"while checking poolname of zfs volume", pvcObj.Spec.VolumeName)
|
||||||
Expect(vol.Spec.FsType).To(Equal(scObj.Parameters["fstype"]),
|
gomega.Expect(vol.Spec.FsType).To(gomega.Equal(scObj.Parameters["fstype"]),
|
||||||
"while checking fstype of zfs volume", pvcObj.Spec.VolumeName)
|
"while checking fstype of zfs volume", pvcObj.Spec.VolumeName)
|
||||||
Expect(vol.Spec.VolumeType).To(Equal(volType),
|
gomega.Expect(vol.Spec.VolumeType).To(gomega.Equal(volType),
|
||||||
"while checking Volume type as dataset", pvcObj.Spec.VolumeName)
|
"while checking Volume type as dataset", pvcObj.Spec.VolumeName)
|
||||||
Expect(vol.Spec.Capacity).To(Equal(capacity),
|
gomega.Expect(vol.Spec.Capacity).To(gomega.Equal(capacity),
|
||||||
"while checking capacity of zfs volume", pvcObj.Spec.VolumeName)
|
"while checking capacity of zfs volume", pvcObj.Spec.VolumeName)
|
||||||
|
|
||||||
// it might fail if we are checking finializer before event is processed by node agent
|
// it might fail if we are checking finializer before event is processed by node agent
|
||||||
Expect(vol.Finalizers[0]).To(Equal(zfs.ZFSFinalizer), "while checking finializer to be set {%s}", pvcObj.Spec.VolumeName)
|
gomega.Expect(vol.Finalizers[0]).To(gomega.Equal(zfs.ZFSFinalizer), "while checking finializer to be set {%s}", pvcObj.Spec.VolumeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VerifyZFSVolumePropEdit verigies the volume properties
|
||||||
func VerifyZFSVolumePropEdit() {
|
func VerifyZFSVolumePropEdit() {
|
||||||
By("verifying compression property update")
|
ginkgo.By("verifying compression property update")
|
||||||
|
|
||||||
By("fetching zfs volume for setting compression=on")
|
ginkgo.By("fetching zfs volume for setting compression=on")
|
||||||
vol, err := ZFSClient.WithNamespace(OpenEBSNamespace).
|
vol, err := ZFSClient.WithNamespace(OpenEBSNamespace).
|
||||||
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
||||||
Expect(err).To(BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
val := "on"
|
val := "on"
|
||||||
vol.Spec.Compression = val
|
vol.Spec.Compression = val
|
||||||
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
||||||
Expect(err).To(BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
status := IsPropUpdatedEventually(vol, "compression", val)
|
status := IsPropUpdatedEventually(vol, "compression", val)
|
||||||
Expect(status).To(Equal(true), "while updating compression=on {%s}", vol.Name)
|
gomega.Expect(status).To(gomega.Equal(true), "while updating compression=on {%s}", vol.Name)
|
||||||
|
|
||||||
By("fetching zfs volume for setting compression=off")
|
ginkgo.By("fetching zfs volume for setting compression=off")
|
||||||
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
||||||
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
||||||
Expect(err).To(BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
val = "off"
|
val = "off"
|
||||||
vol.Spec.Compression = val
|
vol.Spec.Compression = val
|
||||||
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
||||||
Expect(err).To(BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
status = IsPropUpdatedEventually(vol, "compression", val)
|
status = IsPropUpdatedEventually(vol, "compression", val)
|
||||||
Expect(status).To(Equal(true), "while updating compression=off {%s}", vol.Name)
|
gomega.Expect(status).To(gomega.Equal(true), "while updating compression=off {%s}", vol.Name)
|
||||||
|
|
||||||
By("verifying dedup property update")
|
ginkgo.By("verifying dedup property update")
|
||||||
|
|
||||||
By("fetching zfs volume for setting dedup=on")
|
ginkgo.By("fetching zfs volume for setting dedup=on")
|
||||||
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
||||||
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
||||||
Expect(err).To(BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
val = "on"
|
val = "on"
|
||||||
vol.Spec.Dedup = val
|
vol.Spec.Dedup = val
|
||||||
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
||||||
Expect(err).To(BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
status = IsPropUpdatedEventually(vol, "dedup", val)
|
status = IsPropUpdatedEventually(vol, "dedup", val)
|
||||||
Expect(status).To(Equal(true), "while updating dedup=on {%s}", vol.Name)
|
gomega.Expect(status).To(gomega.Equal(true), "while updating dedup=on {%s}", vol.Name)
|
||||||
|
|
||||||
By("fetching zfs volume for setting dedup=off")
|
ginkgo.By("fetching zfs volume for setting dedup=off")
|
||||||
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
||||||
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
||||||
Expect(err).To(BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
val = "off"
|
val = "off"
|
||||||
vol.Spec.Dedup = val
|
vol.Spec.Dedup = val
|
||||||
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
||||||
Expect(err).To(BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
status = IsPropUpdatedEventually(vol, "dedup", val)
|
status = IsPropUpdatedEventually(vol, "dedup", val)
|
||||||
Expect(status).To(Equal(true), "while updating dedup=off {%s}", vol.Name)
|
gomega.Expect(status).To(gomega.Equal(true), "while updating dedup=off {%s}", vol.Name)
|
||||||
|
|
||||||
if vol.Spec.VolumeType == zfs.VOLTYPE_DATASET {
|
if vol.Spec.VolumeType == zfs.VolTypeDataset {
|
||||||
By("verifying recordsize property update")
|
ginkgo.By("verifying recordsize property update")
|
||||||
|
|
||||||
By("fetching zfs volume for setting the recordsize")
|
ginkgo.By("fetching zfs volume for setting the recordsize")
|
||||||
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
||||||
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
||||||
Expect(err).To(BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
val = "4096" // 4k
|
val = "4096" // 4k
|
||||||
vol.Spec.RecordSize = val
|
vol.Spec.RecordSize = val
|
||||||
vol.Spec.VolBlockSize = "8192"
|
vol.Spec.VolBlockSize = "8192"
|
||||||
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
||||||
Expect(err).To(BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
status = IsPropUpdatedEventually(vol, "recordsize", val)
|
status = IsPropUpdatedEventually(vol, "recordsize", val)
|
||||||
Expect(status).To(Equal(true), "while updating redordsize {%s}", vol.Name)
|
gomega.Expect(status).To(gomega.Equal(true), "while updating redordsize {%s}", vol.Name)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Expect(vol.Spec.VolumeType).To(Equal(zfs.VOLTYPE_ZVOL), "voltype should be zvol {%s}", vol.Name)
|
gomega.Expect(vol.Spec.VolumeType).To(gomega.Equal(zfs.VolTypeZVol), "voltype should be zvol {%s}", vol.Name)
|
||||||
|
|
||||||
By("verifying blocksize property update")
|
ginkgo.By("verifying blocksize property update")
|
||||||
|
|
||||||
By("fetching zfs volume for setting the blocksize")
|
ginkgo.By("fetching zfs volume for setting the blocksize")
|
||||||
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
vol, err = ZFSClient.WithNamespace(OpenEBSNamespace).
|
||||||
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
Get(pvcObj.Spec.VolumeName, metav1.GetOptions{})
|
||||||
Expect(err).To(BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while fetching the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
val, err = zfs.GetVolumeProperty(vol, "volblocksize")
|
val, err = zfs.GetVolumeProperty(vol, "volblocksize")
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||||
|
|
||||||
nval := "8192" // 8k
|
nval := "8192" // 8k
|
||||||
vol.Spec.VolBlockSize = nval
|
vol.Spec.VolBlockSize = nval
|
||||||
vol.Spec.RecordSize = "16384"
|
vol.Spec.RecordSize = "16384"
|
||||||
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
_, err = ZFSClient.WithNamespace(OpenEBSNamespace).Update(vol)
|
||||||
Expect(err).To(BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
gomega.Expect(err).To(gomega.BeNil(), "while updating the zfs volume {%s}", vol.Name)
|
||||||
|
|
||||||
status = IsPropUpdatedEventually(vol, "volblocksize", val)
|
status = IsPropUpdatedEventually(vol, "volblocksize", val)
|
||||||
Expect(status).To(Equal(true), "while updating volblocksize {%s}", vol.Name)
|
gomega.Expect(status).To(gomega.Equal(true), "while updating volblocksize {%s}", vol.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteStorageClass() {
|
func deleteStorageClass() {
|
||||||
err := SCClient.Delete(scObj.Name, &metav1.DeleteOptions{})
|
err := SCClient.Delete(scObj.Name, &metav1.DeleteOptions{})
|
||||||
Expect(err).To(BeNil(),
|
gomega.Expect(err).To(gomega.BeNil(),
|
||||||
"while deleting zfs storageclass {%s}", scObj.Name)
|
"while deleting zfs storageclass {%s}", scObj.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -305,38 +308,38 @@ func createAndVerifyPVC() {
|
||||||
err error
|
err error
|
||||||
pvcName = "zfspv-pvc"
|
pvcName = "zfspv-pvc"
|
||||||
)
|
)
|
||||||
By("building a pvc")
|
ginkgo.By("building a pvc")
|
||||||
pvcObj, err = pvc.NewBuilder().
|
pvcObj, err = pvc.NewBuilder().
|
||||||
WithName(pvcName).
|
WithName(pvcName).
|
||||||
WithNamespace(OpenEBSNamespace).
|
WithNamespace(OpenEBSNamespace).
|
||||||
WithStorageClass(scObj.Name).
|
WithStorageClass(scObj.Name).
|
||||||
WithAccessModes(accessModes).
|
WithAccessModes(accessModes).
|
||||||
WithCapacity(capacity).Build()
|
WithCapacity(capacity).Build()
|
||||||
Expect(err).ShouldNot(
|
gomega.Expect(err).ShouldNot(
|
||||||
HaveOccurred(),
|
gomega.HaveOccurred(),
|
||||||
"while building pvc {%s} in namespace {%s}",
|
"while building pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
)
|
)
|
||||||
|
|
||||||
By("creating above pvc")
|
ginkgo.By("creating above pvc")
|
||||||
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Create(pvcObj)
|
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Create(pvcObj)
|
||||||
Expect(err).To(
|
gomega.Expect(err).To(
|
||||||
BeNil(),
|
gomega.BeNil(),
|
||||||
"while creating pvc {%s} in namespace {%s}",
|
"while creating pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
)
|
)
|
||||||
|
|
||||||
By("verifying pvc status as bound")
|
ginkgo.By("verifying pvc status as bound")
|
||||||
|
|
||||||
status := IsPVCBoundEventually(pvcName)
|
status := IsPVCBoundEventually(pvcName)
|
||||||
Expect(status).To(Equal(true),
|
gomega.Expect(status).To(gomega.Equal(true),
|
||||||
"while checking status equal to bound")
|
"while checking status equal to bound")
|
||||||
|
|
||||||
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{})
|
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{})
|
||||||
Expect(err).To(
|
gomega.Expect(err).To(
|
||||||
BeNil(),
|
gomega.BeNil(),
|
||||||
"while retrieving pvc {%s} in namespace {%s}",
|
"while retrieving pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
|
|
@ -351,7 +354,7 @@ func createAndVerifyBlockPVC() {
|
||||||
|
|
||||||
volmode := corev1.PersistentVolumeBlock
|
volmode := corev1.PersistentVolumeBlock
|
||||||
|
|
||||||
By("building a pvc")
|
ginkgo.By("building a pvc")
|
||||||
pvcObj, err = pvc.NewBuilder().
|
pvcObj, err = pvc.NewBuilder().
|
||||||
WithName(pvcName).
|
WithName(pvcName).
|
||||||
WithNamespace(OpenEBSNamespace).
|
WithNamespace(OpenEBSNamespace).
|
||||||
|
|
@ -359,31 +362,31 @@ func createAndVerifyBlockPVC() {
|
||||||
WithAccessModes(accessModes).
|
WithAccessModes(accessModes).
|
||||||
WithVolumeMode(&volmode).
|
WithVolumeMode(&volmode).
|
||||||
WithCapacity(capacity).Build()
|
WithCapacity(capacity).Build()
|
||||||
Expect(err).ShouldNot(
|
gomega.Expect(err).ShouldNot(
|
||||||
HaveOccurred(),
|
gomega.HaveOccurred(),
|
||||||
"while building pvc {%s} in namespace {%s}",
|
"while building pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
)
|
)
|
||||||
|
|
||||||
By("creating above pvc")
|
ginkgo.By("creating above pvc")
|
||||||
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Create(pvcObj)
|
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Create(pvcObj)
|
||||||
Expect(err).To(
|
gomega.Expect(err).To(
|
||||||
BeNil(),
|
gomega.BeNil(),
|
||||||
"while creating pvc {%s} in namespace {%s}",
|
"while creating pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
)
|
)
|
||||||
|
|
||||||
By("verifying pvc status as bound")
|
ginkgo.By("verifying pvc status as bound")
|
||||||
|
|
||||||
status := IsPVCBoundEventually(pvcName)
|
status := IsPVCBoundEventually(pvcName)
|
||||||
Expect(status).To(Equal(true),
|
gomega.Expect(status).To(gomega.Equal(true),
|
||||||
"while checking status equal to bound")
|
"while checking status equal to bound")
|
||||||
|
|
||||||
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{})
|
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{})
|
||||||
Expect(err).To(
|
gomega.Expect(err).To(
|
||||||
BeNil(),
|
gomega.BeNil(),
|
||||||
"while retrieving pvc {%s} in namespace {%s}",
|
"while retrieving pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
|
|
@ -395,46 +398,46 @@ func resizeAndVerifyPVC() {
|
||||||
err error
|
err error
|
||||||
pvcName = "zfspv-pvc"
|
pvcName = "zfspv-pvc"
|
||||||
)
|
)
|
||||||
By("updating the pvc with new size")
|
ginkgo.By("updating the pvc with new size")
|
||||||
pvcObj, err = pvc.BuildFrom(pvcObj).
|
pvcObj, err = pvc.BuildFrom(pvcObj).
|
||||||
WithCapacity(NewCapacity).Build()
|
WithCapacity(NewCapacity).Build()
|
||||||
Expect(err).To(
|
gomega.Expect(err).To(
|
||||||
BeNil(),
|
gomega.BeNil(),
|
||||||
"while building pvc {%s} in namespace {%s}",
|
"while building pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
)
|
)
|
||||||
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Update(pvcObj)
|
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Update(pvcObj)
|
||||||
Expect(err).To(
|
gomega.Expect(err).To(
|
||||||
BeNil(),
|
gomega.BeNil(),
|
||||||
"while updating pvc {%s} in namespace {%s}",
|
"while updating pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
)
|
)
|
||||||
|
|
||||||
By("verifying pvc size to be updated")
|
ginkgo.By("verifying pvc size to be updated")
|
||||||
|
|
||||||
status := IsPVCResizedEventually(pvcName, NewCapacity)
|
status := IsPVCResizedEventually(pvcName, NewCapacity)
|
||||||
Expect(status).To(Equal(true),
|
gomega.Expect(status).To(gomega.Equal(true),
|
||||||
"while checking pvc resize")
|
"while checking pvc resize")
|
||||||
|
|
||||||
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{})
|
pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{})
|
||||||
Expect(err).To(
|
gomega.Expect(err).To(
|
||||||
BeNil(),
|
gomega.BeNil(),
|
||||||
"while retrieving pvc {%s} in namespace {%s}",
|
"while retrieving pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
func createDeployVerifyApp() {
|
func createDeployVerifyApp() {
|
||||||
By("creating and deploying app pod", createAndDeployAppPod)
|
ginkgo.By("creating and deploying app pod", createAndDeployAppPod)
|
||||||
time.Sleep(30 * time.Second)
|
time.Sleep(30 * time.Second)
|
||||||
By("verifying app pod is running", verifyAppPodRunning)
|
ginkgo.By("verifying app pod is running", verifyAppPodRunning)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createAndDeployAppPod() {
|
func createAndDeployAppPod() {
|
||||||
var err error
|
var err error
|
||||||
By("building a busybox app pod deployment using above zfs volume")
|
ginkgo.By("building a busybox app pod deployment using above zfs volume")
|
||||||
deployObj, err = deploy.NewBuilder().
|
deployObj, err = deploy.NewBuilder().
|
||||||
WithName(appName).
|
WithName(appName).
|
||||||
WithNamespace(OpenEBSNamespace).
|
WithNamespace(OpenEBSNamespace).
|
||||||
|
|
@ -484,11 +487,11 @@ func createAndDeployAppPod() {
|
||||||
).
|
).
|
||||||
Build()
|
Build()
|
||||||
|
|
||||||
Expect(err).ShouldNot(HaveOccurred(), "while building app deployement {%s}", appName)
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), "while building app deployement {%s}", appName)
|
||||||
|
|
||||||
deployObj, err = DeployClient.WithNamespace(OpenEBSNamespace).Create(deployObj)
|
deployObj, err = DeployClient.WithNamespace(OpenEBSNamespace).Create(deployObj)
|
||||||
Expect(err).ShouldNot(
|
gomega.Expect(err).ShouldNot(
|
||||||
HaveOccurred(),
|
gomega.HaveOccurred(),
|
||||||
"while creating pod {%s} in namespace {%s}",
|
"while creating pod {%s} in namespace {%s}",
|
||||||
appName,
|
appName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
|
|
@ -497,7 +500,7 @@ func createAndDeployAppPod() {
|
||||||
|
|
||||||
func createAndDeployBlockAppPod() {
|
func createAndDeployBlockAppPod() {
|
||||||
var err error
|
var err error
|
||||||
By("building a busybox app pod deployment using above zfs volume")
|
ginkgo.By("building a busybox app pod deployment using above zfs volume")
|
||||||
deployObj, err = deploy.NewBuilder().
|
deployObj, err = deploy.NewBuilder().
|
||||||
WithName(appName).
|
WithName(appName).
|
||||||
WithNamespace(OpenEBSNamespace).
|
WithNamespace(OpenEBSNamespace).
|
||||||
|
|
@ -547,11 +550,11 @@ func createAndDeployBlockAppPod() {
|
||||||
).
|
).
|
||||||
Build()
|
Build()
|
||||||
|
|
||||||
Expect(err).ShouldNot(HaveOccurred(), "while building app deployement {%s}", appName)
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), "while building app deployement {%s}", appName)
|
||||||
|
|
||||||
deployObj, err = DeployClient.WithNamespace(OpenEBSNamespace).Create(deployObj)
|
deployObj, err = DeployClient.WithNamespace(OpenEBSNamespace).Create(deployObj)
|
||||||
Expect(err).ShouldNot(
|
gomega.Expect(err).ShouldNot(
|
||||||
HaveOccurred(),
|
gomega.HaveOccurred(),
|
||||||
"while creating pod {%s} in namespace {%s}",
|
"while creating pod {%s} in namespace {%s}",
|
||||||
appName,
|
appName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
|
|
@ -559,9 +562,9 @@ func createAndDeployBlockAppPod() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDeployVerifyBlockApp() {
|
func createDeployVerifyBlockApp() {
|
||||||
By("creating and deploying app pod", createAndDeployBlockAppPod)
|
ginkgo.By("creating and deploying app pod", createAndDeployBlockAppPod)
|
||||||
time.Sleep(30 * time.Second)
|
time.Sleep(30 * time.Second)
|
||||||
By("verifying app pod is running", verifyAppPodRunning)
|
ginkgo.By("verifying app pod is running", verifyAppPodRunning)
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyAppPodRunning() {
|
func verifyAppPodRunning() {
|
||||||
|
|
@ -571,28 +574,28 @@ func verifyAppPodRunning() {
|
||||||
LabelSelector: "app=busybox",
|
LabelSelector: "app=busybox",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
Expect(err).ShouldNot(HaveOccurred(), "while verifying application pod")
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), "while verifying application pod")
|
||||||
|
|
||||||
status := IsPodRunningEventually(OpenEBSNamespace, appPod.Items[0].Name)
|
status := IsPodRunningEventually(OpenEBSNamespace, appPod.Items[0].Name)
|
||||||
Expect(status).To(Equal(true), "while checking status of pod {%s}", appPod.Items[0].Name)
|
gomega.Expect(status).To(gomega.Equal(true), "while checking status of pod {%s}", appPod.Items[0].Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteAppDeployment() {
|
func deleteAppDeployment() {
|
||||||
err := DeployClient.WithNamespace(OpenEBSNamespace).
|
err := DeployClient.WithNamespace(OpenEBSNamespace).
|
||||||
Delete(deployObj.Name, &metav1.DeleteOptions{})
|
Delete(deployObj.Name, &metav1.DeleteOptions{})
|
||||||
Expect(err).ShouldNot(HaveOccurred(), "while deleting application pod")
|
gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), "while deleting application pod")
|
||||||
}
|
}
|
||||||
|
|
||||||
func deletePVC() {
|
func deletePVC() {
|
||||||
err := PVCClient.WithNamespace(OpenEBSNamespace).Delete(pvcName, &metav1.DeleteOptions{})
|
err := PVCClient.WithNamespace(OpenEBSNamespace).Delete(pvcName, &metav1.DeleteOptions{})
|
||||||
Expect(err).To(
|
gomega.Expect(err).To(
|
||||||
BeNil(),
|
gomega.BeNil(),
|
||||||
"while deleting pvc {%s} in namespace {%s}",
|
"while deleting pvc {%s} in namespace {%s}",
|
||||||
pvcName,
|
pvcName,
|
||||||
OpenEBSNamespace,
|
OpenEBSNamespace,
|
||||||
)
|
)
|
||||||
By("verifying deleted pvc")
|
ginkgo.By("verifying deleted pvc")
|
||||||
status := IsPVCDeletedEventually(pvcName)
|
status := IsPVCDeletedEventually(pvcName)
|
||||||
Expect(status).To(Equal(true), "while trying to get deleted pvc")
|
gomega.Expect(status).To(gomega.Equal(true), "while trying to get deleted pvc")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue