Add generated file
This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
59
vendor/k8s.io/kubernetes/pkg/volume/quobyte/BUILD
generated
vendored
Normal file
59
vendor/k8s.io/kubernetes/pkg/volume/quobyte/BUILD
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"quobyte.go",
|
||||
"quobyte_util.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/volume/quobyte",
|
||||
deps = [
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/util/strings:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/pborman/uuid:go_default_library",
|
||||
"//vendor/github.com/quobyte/api:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["quobyte_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/testing:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
10
vendor/k8s.io/kubernetes/pkg/volume/quobyte/OWNERS
generated
vendored
Normal file
10
vendor/k8s.io/kubernetes/pkg/volume/quobyte/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
approvers:
|
||||
- rootfs
|
||||
- saad-ali
|
||||
reviewers:
|
||||
- johscheuer
|
||||
- saad-ali
|
||||
- jsafrane
|
||||
- rootfs
|
||||
- jingxu97
|
||||
- msau42
|
19
vendor/k8s.io/kubernetes/pkg/volume/quobyte/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/kubernetes/pkg/volume/quobyte/doc.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package quobyte contains the internal representation of Quobyte
|
||||
// volumes.
|
||||
package quobyte
|
494
vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte.go
generated
vendored
Normal file
494
vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte.go
generated
vendored
Normal file
@@ -0,0 +1,494 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package quobyte
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
gostrings "strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/pborman/uuid"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/util/strings"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
// ProbeVolumePlugins is the primary entrypoint for volume plugins.
|
||||
func ProbeVolumePlugins() []volume.VolumePlugin {
|
||||
return []volume.VolumePlugin{&quobytePlugin{nil}}
|
||||
}
|
||||
|
||||
type quobytePlugin struct {
|
||||
host volume.VolumeHost
|
||||
}
|
||||
|
||||
// This user is used to authenticate against the
|
||||
// Quobyte API server and holds all information
|
||||
type quobyteAPIConfig struct {
|
||||
quobyteUser string
|
||||
quobytePassword string
|
||||
quobyteAPIServer string
|
||||
}
|
||||
|
||||
var _ volume.VolumePlugin = &quobytePlugin{}
|
||||
var _ volume.PersistentVolumePlugin = &quobytePlugin{}
|
||||
var _ volume.DeletableVolumePlugin = &quobytePlugin{}
|
||||
var _ volume.ProvisionableVolumePlugin = &quobytePlugin{}
|
||||
var _ volume.Provisioner = &quobyteVolumeProvisioner{}
|
||||
var _ volume.Deleter = &quobyteVolumeDeleter{}
|
||||
|
||||
const (
|
||||
quobytePluginName = "kubernetes.io/quobyte"
|
||||
)
|
||||
|
||||
func (plugin *quobytePlugin) Init(host volume.VolumeHost) error {
|
||||
plugin.host = host
|
||||
return nil
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) GetPluginName() string {
|
||||
return quobytePluginName
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) GetVolumeName(spec *volume.Spec) (string, error) {
|
||||
volumeSource, _, err := getVolumeSource(spec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%v:%v",
|
||||
volumeSource.Registry,
|
||||
volumeSource.Volume), nil
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) CanSupport(spec *volume.Spec) bool {
|
||||
if (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Quobyte == nil) ||
|
||||
(spec.Volume != nil && spec.Volume.Quobyte == nil) {
|
||||
return false
|
||||
}
|
||||
|
||||
// If Quobyte is already mounted we don't need to check if the binary is installed
|
||||
if mounter, err := plugin.newMounterInternal(spec, nil, plugin.host.GetMounter(plugin.GetPluginName())); err == nil {
|
||||
qm, _ := mounter.(*quobyteMounter)
|
||||
pluginDir := plugin.host.GetPluginDir(strings.EscapeQualifiedNameForDisk(quobytePluginName))
|
||||
if mounted, err := qm.pluginDirIsMounted(pluginDir); mounted && err == nil {
|
||||
glog.V(4).Infof("quobyte: can support")
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
glog.V(4).Infof("quobyte: Error: %v", err)
|
||||
}
|
||||
|
||||
exec := plugin.host.GetExec(plugin.GetPluginName())
|
||||
if out, err := exec.Run("ls", "/sbin/mount.quobyte"); err == nil {
|
||||
glog.V(4).Infof("quobyte: can support: %s", string(out))
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) RequiresRemount() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) SupportsMountOption() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) SupportsBulkVolumeVerification() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) GetAccessModes() []v1.PersistentVolumeAccessMode {
|
||||
return []v1.PersistentVolumeAccessMode{
|
||||
v1.ReadWriteOnce,
|
||||
v1.ReadOnlyMany,
|
||||
v1.ReadWriteMany,
|
||||
}
|
||||
}
|
||||
|
||||
func getVolumeSource(spec *volume.Spec) (*v1.QuobyteVolumeSource, bool, error) {
|
||||
if spec.Volume != nil && spec.Volume.Quobyte != nil {
|
||||
return spec.Volume.Quobyte, spec.Volume.Quobyte.ReadOnly, nil
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.Quobyte != nil {
|
||||
return spec.PersistentVolume.Spec.Quobyte, spec.ReadOnly, nil
|
||||
}
|
||||
|
||||
return nil, false, fmt.Errorf("Spec does not reference a Quobyte volume type")
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) {
|
||||
quobyteVolume := &v1.Volume{
|
||||
Name: volumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Quobyte: &v1.QuobyteVolumeSource{
|
||||
Volume: volumeName,
|
||||
},
|
||||
},
|
||||
}
|
||||
return volume.NewSpecFromVolume(quobyteVolume), nil
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.Mounter, error) {
|
||||
return plugin.newMounterInternal(spec, pod, plugin.host.GetMounter(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod, mounter mount.Interface) (volume.Mounter, error) {
|
||||
source, readOnly, err := getVolumeSource(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &quobyteMounter{
|
||||
quobyte: &quobyte{
|
||||
volName: spec.Name(),
|
||||
user: source.User,
|
||||
group: source.Group,
|
||||
mounter: mounter,
|
||||
pod: pod,
|
||||
volume: source.Volume,
|
||||
plugin: plugin,
|
||||
},
|
||||
registry: source.Registry,
|
||||
readOnly: readOnly,
|
||||
mountOptions: util.MountOptionFromSpec(spec),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) {
|
||||
return plugin.newUnmounterInternal(volName, podUID, plugin.host.GetMounter(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) newUnmounterInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Unmounter, error) {
|
||||
return &quobyteUnmounter{
|
||||
&quobyte{
|
||||
volName: volName,
|
||||
mounter: mounter,
|
||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: podUID}},
|
||||
plugin: plugin,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Quobyte volumes represent a bare host directory mount of an quobyte export.
|
||||
type quobyte struct {
|
||||
volName string
|
||||
pod *v1.Pod
|
||||
user string
|
||||
group string
|
||||
volume string
|
||||
tenant string
|
||||
config string
|
||||
mounter mount.Interface
|
||||
plugin *quobytePlugin
|
||||
volume.MetricsNil
|
||||
}
|
||||
|
||||
type quobyteMounter struct {
|
||||
*quobyte
|
||||
registry string
|
||||
readOnly bool
|
||||
mountOptions []string
|
||||
}
|
||||
|
||||
var _ volume.Mounter = &quobyteMounter{}
|
||||
|
||||
func (mounter *quobyteMounter) GetAttributes() volume.Attributes {
|
||||
return volume.Attributes{
|
||||
ReadOnly: mounter.readOnly,
|
||||
Managed: false,
|
||||
SupportsSELinux: false,
|
||||
}
|
||||
}
|
||||
|
||||
// Checks prior to mount operations to verify that the required components (binaries, etc.)
|
||||
// to mount the volume are available on the underlying node.
|
||||
// If not, it returns an error
|
||||
func (mounter *quobyteMounter) CanMount() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUp attaches the disk and bind mounts to the volume path.
|
||||
func (mounter *quobyteMounter) SetUp(fsGroup *int64) error {
|
||||
pluginDir := mounter.plugin.host.GetPluginDir(strings.EscapeQualifiedNameForDisk(quobytePluginName))
|
||||
return mounter.SetUpAt(pluginDir, fsGroup)
|
||||
}
|
||||
|
||||
func (mounter *quobyteMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
// Check if Quobyte is already mounted on the host in the Plugin Dir
|
||||
// if so we can use this mountpoint instead of creating a new one
|
||||
// IsLikelyNotMountPoint wouldn't check the mount type
|
||||
if mounted, err := mounter.pluginDirIsMounted(dir); err != nil {
|
||||
return err
|
||||
} else if mounted {
|
||||
return nil
|
||||
}
|
||||
|
||||
os.MkdirAll(dir, 0750)
|
||||
var options []string
|
||||
if mounter.readOnly {
|
||||
options = append(options, "ro")
|
||||
}
|
||||
|
||||
//if a trailing slash is missing we add it here
|
||||
mountOptions := util.JoinMountOptions(mounter.mountOptions, options)
|
||||
if err := mounter.mounter.Mount(mounter.correctTraillingSlash(mounter.registry), dir, "quobyte", mountOptions); err != nil {
|
||||
return fmt.Errorf("quobyte: mount failed: %v", err)
|
||||
}
|
||||
|
||||
glog.V(4).Infof("quobyte: mount set up: %s", dir)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPath returns the path to the user specific mount of a Quobyte volume
|
||||
// Returns a path in the format ../user#group@volume
|
||||
func (quobyteVolume *quobyte) GetPath() string {
|
||||
user := quobyteVolume.user
|
||||
if len(user) == 0 {
|
||||
user = "root"
|
||||
}
|
||||
|
||||
group := quobyteVolume.group
|
||||
if len(group) == 0 {
|
||||
group = "nfsnobody"
|
||||
}
|
||||
|
||||
// Quobyte has only one mount in the PluginDir where all Volumes are mounted
|
||||
// The Quobyte client does a fixed-user mapping
|
||||
pluginDir := quobyteVolume.plugin.host.GetPluginDir(strings.EscapeQualifiedNameForDisk(quobytePluginName))
|
||||
return path.Join(pluginDir, fmt.Sprintf("%s#%s@%s", user, group, quobyteVolume.volume))
|
||||
}
|
||||
|
||||
type quobyteUnmounter struct {
|
||||
*quobyte
|
||||
}
|
||||
|
||||
var _ volume.Unmounter = &quobyteUnmounter{}
|
||||
|
||||
func (unmounter *quobyteUnmounter) TearDown() error {
|
||||
return unmounter.TearDownAt(unmounter.GetPath())
|
||||
}
|
||||
|
||||
// We don't need to unmount on the host because only one mount exists
|
||||
func (unmounter *quobyteUnmounter) TearDownAt(dir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type quobyteVolumeDeleter struct {
|
||||
*quobyteMounter
|
||||
pv *v1.PersistentVolume
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) NewDeleter(spec *volume.Spec) (volume.Deleter, error) {
|
||||
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Quobyte == nil {
|
||||
return nil, fmt.Errorf("spec.PersistentVolumeSource.Spec.Quobyte is nil")
|
||||
}
|
||||
|
||||
return plugin.newDeleterInternal(spec)
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) newDeleterInternal(spec *volume.Spec) (volume.Deleter, error) {
|
||||
source, readOnly, err := getVolumeSource(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &quobyteVolumeDeleter{
|
||||
quobyteMounter: &quobyteMounter{
|
||||
quobyte: &quobyte{
|
||||
volName: spec.Name(),
|
||||
user: source.User,
|
||||
group: source.Group,
|
||||
volume: source.Volume,
|
||||
plugin: plugin,
|
||||
},
|
||||
registry: source.Registry,
|
||||
readOnly: readOnly,
|
||||
},
|
||||
pv: spec.PersistentVolume,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) NewProvisioner(options volume.VolumeOptions) (volume.Provisioner, error) {
|
||||
return plugin.newProvisionerInternal(options)
|
||||
}
|
||||
|
||||
func (plugin *quobytePlugin) newProvisionerInternal(options volume.VolumeOptions) (volume.Provisioner, error) {
|
||||
return &quobyteVolumeProvisioner{
|
||||
quobyteMounter: &quobyteMounter{
|
||||
quobyte: &quobyte{
|
||||
plugin: plugin,
|
||||
},
|
||||
},
|
||||
options: options,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type quobyteVolumeProvisioner struct {
|
||||
*quobyteMounter
|
||||
options volume.VolumeOptions
|
||||
}
|
||||
|
||||
func (provisioner *quobyteVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopologies []v1.TopologySelectorTerm) (*v1.PersistentVolume, error) {
|
||||
if !util.AccessModesContainedInAll(provisioner.plugin.GetAccessModes(), provisioner.options.PVC.Spec.AccessModes) {
|
||||
return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", provisioner.options.PVC.Spec.AccessModes, provisioner.plugin.GetAccessModes())
|
||||
}
|
||||
|
||||
if util.CheckPersistentVolumeClaimModeBlock(provisioner.options.PVC) {
|
||||
return nil, fmt.Errorf("%s does not support block volume provisioning", provisioner.plugin.GetPluginName())
|
||||
}
|
||||
|
||||
if provisioner.options.PVC.Spec.Selector != nil {
|
||||
return nil, fmt.Errorf("claim Selector is not supported")
|
||||
}
|
||||
provisioner.config = "BASE"
|
||||
provisioner.tenant = "DEFAULT"
|
||||
createQuota := false
|
||||
|
||||
cfg, err := parseAPIConfig(provisioner.plugin, provisioner.options.Parameters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range provisioner.options.Parameters {
|
||||
switch gostrings.ToLower(k) {
|
||||
case "registry":
|
||||
provisioner.registry = v
|
||||
case "user":
|
||||
provisioner.user = v
|
||||
case "group":
|
||||
provisioner.group = v
|
||||
case "quobytetenant":
|
||||
provisioner.tenant = v
|
||||
case "quobyteconfig":
|
||||
provisioner.config = v
|
||||
case "createquota":
|
||||
createQuota = gostrings.ToLower(v) == "true"
|
||||
case "adminsecretname",
|
||||
"adminsecretnamespace",
|
||||
"quobyteapiserver":
|
||||
continue
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid option %q for volume plugin %s", k, provisioner.plugin.GetPluginName())
|
||||
}
|
||||
}
|
||||
|
||||
if !validateRegistry(provisioner.registry) {
|
||||
return nil, fmt.Errorf("Quobyte registry missing or malformed: must be a host:port pair or multiple pairs separated by commas")
|
||||
}
|
||||
|
||||
// create random image name
|
||||
provisioner.volume = fmt.Sprintf("kubernetes-dynamic-pvc-%s", uuid.NewUUID())
|
||||
|
||||
manager := &quobyteVolumeManager{
|
||||
config: cfg,
|
||||
}
|
||||
|
||||
vol, sizeGB, err := manager.createVolume(provisioner, createQuota)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pv := new(v1.PersistentVolume)
|
||||
metav1.SetMetaDataAnnotation(&pv.ObjectMeta, util.VolumeDynamicallyCreatedByKey, "quobyte-dynamic-provisioner")
|
||||
pv.Spec.PersistentVolumeSource.Quobyte = vol
|
||||
pv.Spec.PersistentVolumeReclaimPolicy = provisioner.options.PersistentVolumeReclaimPolicy
|
||||
pv.Spec.AccessModes = provisioner.options.PVC.Spec.AccessModes
|
||||
if len(pv.Spec.AccessModes) == 0 {
|
||||
pv.Spec.AccessModes = provisioner.plugin.GetAccessModes()
|
||||
}
|
||||
pv.Spec.Capacity = v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)),
|
||||
}
|
||||
pv.Spec.MountOptions = provisioner.options.MountOptions
|
||||
return pv, nil
|
||||
}
|
||||
|
||||
func (deleter *quobyteVolumeDeleter) GetPath() string {
|
||||
return deleter.quobyte.GetPath()
|
||||
}
|
||||
|
||||
func (deleter *quobyteVolumeDeleter) Delete() error {
|
||||
class, err := util.GetClassForVolume(deleter.plugin.host.GetKubeClient(), deleter.pv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg, err := parseAPIConfig(deleter.plugin, class.Parameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
manager := &quobyteVolumeManager{
|
||||
config: cfg,
|
||||
}
|
||||
return manager.deleteVolume(deleter)
|
||||
}
|
||||
|
||||
// Parse API configuration (url, username and password) out of class.Parameters.
|
||||
func parseAPIConfig(plugin *quobytePlugin, params map[string]string) (*quobyteAPIConfig, error) {
|
||||
var apiServer, secretName string
|
||||
secretNamespace := "default"
|
||||
|
||||
deleteKeys := []string{}
|
||||
|
||||
for k, v := range params {
|
||||
switch gostrings.ToLower(k) {
|
||||
case "adminsecretname":
|
||||
secretName = v
|
||||
deleteKeys = append(deleteKeys, k)
|
||||
case "adminsecretnamespace":
|
||||
secretNamespace = v
|
||||
deleteKeys = append(deleteKeys, k)
|
||||
case "quobyteapiserver":
|
||||
apiServer = v
|
||||
deleteKeys = append(deleteKeys, k)
|
||||
}
|
||||
}
|
||||
|
||||
if len(apiServer) == 0 {
|
||||
return nil, fmt.Errorf("Quobyte API server missing or malformed: must be a http(s)://host:port pair or multiple pairs separated by commas")
|
||||
}
|
||||
|
||||
secretMap, err := util.GetSecretForPV(secretNamespace, secretName, quobytePluginName, plugin.host.GetKubeClient())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg := &quobyteAPIConfig{
|
||||
quobyteAPIServer: apiServer,
|
||||
}
|
||||
|
||||
var ok bool
|
||||
if cfg.quobyteUser, ok = secretMap["user"]; !ok {
|
||||
return nil, fmt.Errorf("Missing \"user\" in secret %s/%s", secretNamespace, secretName)
|
||||
}
|
||||
|
||||
if cfg.quobytePassword, ok = secretMap["password"]; !ok {
|
||||
return nil, fmt.Errorf("Missing \"password\" in secret %s/%s", secretNamespace, secretName)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
195
vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte_test.go
generated
vendored
Normal file
195
vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte_test.go
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package quobyte
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
)
|
||||
|
||||
func TestCanSupport(t *testing.T) {
|
||||
tmpDir, err := utiltesting.MkTmpdir("quobyte_test")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plugMgr := volume.VolumePluginMgr{}
|
||||
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(tmpDir, nil, nil))
|
||||
plug, err := plugMgr.FindPluginByName("kubernetes.io/quobyte")
|
||||
if err != nil {
|
||||
t.Errorf("Can't find the plugin by name")
|
||||
}
|
||||
if plug.GetPluginName() != "kubernetes.io/quobyte" {
|
||||
t.Errorf("Wrong name: %s", plug.GetPluginName())
|
||||
}
|
||||
if plug.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{}}}}) {
|
||||
t.Errorf("Expected false")
|
||||
}
|
||||
if plug.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{}}}) {
|
||||
t.Errorf("Expected false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccessModes(t *testing.T) {
|
||||
tmpDir, err := utiltesting.MkTmpdir("quobyte_test")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plugMgr := volume.VolumePluginMgr{}
|
||||
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(tmpDir, nil, nil))
|
||||
|
||||
plug, err := plugMgr.FindPersistentPluginByName("kubernetes.io/quobyte")
|
||||
if err != nil {
|
||||
t.Errorf("Can't find the plugin by name")
|
||||
}
|
||||
if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteMany) {
|
||||
t.Errorf("Expected three AccessModeTypes: %s, %s, and %s", v1.ReadWriteOnce, v1.ReadOnlyMany, v1.ReadWriteMany)
|
||||
}
|
||||
}
|
||||
|
||||
func doTestPlugin(t *testing.T, spec *volume.Spec) {
|
||||
tmpDir, err := utiltesting.MkTmpdir("quobyte_test")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plugMgr := volume.VolumePluginMgr{}
|
||||
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(tmpDir, nil, nil))
|
||||
plug, err := plugMgr.FindPluginByName("kubernetes.io/quobyte")
|
||||
if err != nil {
|
||||
t.Errorf("Can't find the plugin by name")
|
||||
}
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||
mounter, err := plug.(*quobytePlugin).newMounterInternal(spec, pod, &mount.FakeMounter{})
|
||||
volumePath := mounter.GetPath()
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
if mounter == nil {
|
||||
t.Error("Got a nil Mounter")
|
||||
}
|
||||
|
||||
if volumePath != fmt.Sprintf("%s/plugins/kubernetes.io~quobyte/root#root@vol", tmpDir) {
|
||||
t.Errorf("Got unexpected path: %s expected: %s", volumePath, fmt.Sprintf("%s/plugins/kubernetes.io~quobyte/root#root@vol", tmpDir))
|
||||
}
|
||||
if err := mounter.SetUp(nil); err != nil {
|
||||
t.Errorf("Expected success, got: %v", err)
|
||||
}
|
||||
unmounter, err := plug.(*quobytePlugin).newUnmounterInternal("vol", types.UID("poduid"), &mount.FakeMounter{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new unmounter: %v", err)
|
||||
}
|
||||
if unmounter == nil {
|
||||
t.Error("Got a nil unmounter")
|
||||
}
|
||||
if err := unmounter.TearDown(); err != nil {
|
||||
t.Errorf("Expected success, got: %v", err)
|
||||
}
|
||||
// We don't need to check tear down, we don't unmount quobyte
|
||||
}
|
||||
|
||||
func TestPluginVolume(t *testing.T) {
|
||||
vol := &v1.Volume{
|
||||
Name: "vol1",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Quobyte: &v1.QuobyteVolumeSource{Registry: "reg:7861", Volume: "vol", ReadOnly: false, User: "root", Group: "root"},
|
||||
},
|
||||
}
|
||||
doTestPlugin(t, volume.NewSpecFromVolume(vol))
|
||||
}
|
||||
|
||||
func TestPluginPersistentVolume(t *testing.T) {
|
||||
vol := &v1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "vol1",
|
||||
},
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||
Quobyte: &v1.QuobyteVolumeSource{Registry: "reg:7861", Volume: "vol", ReadOnly: false, User: "root", Group: "root"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false))
|
||||
}
|
||||
|
||||
func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||
pv := &v1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvA",
|
||||
},
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||
Quobyte: &v1.QuobyteVolumeSource{Registry: "reg:7861", Volume: "vol", ReadOnly: false, User: "root", Group: "root"},
|
||||
},
|
||||
ClaimRef: &v1.ObjectReference{
|
||||
Name: "claimA",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
claim := &v1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "claimA",
|
||||
Namespace: "nsA",
|
||||
},
|
||||
Spec: v1.PersistentVolumeClaimSpec{
|
||||
VolumeName: "pvA",
|
||||
},
|
||||
Status: v1.PersistentVolumeClaimStatus{
|
||||
Phase: v1.ClaimBound,
|
||||
},
|
||||
}
|
||||
|
||||
tmpDir, err := utiltesting.MkTmpdir("quobyte_test")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
client := fake.NewSimpleClientset(pv, claim)
|
||||
plugMgr := volume.VolumePluginMgr{}
|
||||
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(tmpDir, client, nil))
|
||||
plug, _ := plugMgr.FindPluginByName(quobytePluginName)
|
||||
|
||||
// readOnly bool is supplied by persistent-claim volume source when its mounter creates other volumes
|
||||
spec := volume.NewSpecFromPersistentVolume(pv, true)
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||
mounter, _ := plug.NewMounter(spec, pod, volume.VolumeOptions{})
|
||||
if mounter == nil {
|
||||
t.Fatalf("Got a nil Mounter")
|
||||
}
|
||||
|
||||
if !mounter.GetAttributes().ReadOnly {
|
||||
t.Errorf("Expected true for mounter.IsReadOnly")
|
||||
}
|
||||
}
|
120
vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte_util.go
generated
vendored
Normal file
120
vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte_util.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package quobyte
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
|
||||
"github.com/golang/glog"
|
||||
quobyteapi "github.com/quobyte/api"
|
||||
)
|
||||
|
||||
type quobyteVolumeManager struct {
|
||||
config *quobyteAPIConfig
|
||||
}
|
||||
|
||||
func (manager *quobyteVolumeManager) createVolume(provisioner *quobyteVolumeProvisioner, createQuota bool) (quobyte *v1.QuobyteVolumeSource, size int, err error) {
|
||||
capacity := provisioner.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||
volumeSize := int(util.RoundUpSize(capacity.Value(), 1024*1024*1024))
|
||||
// Quobyte has the concept of Volumes which doen't have a specific size (they can grow unlimited)
|
||||
// to simulate a size constraint we set here a Quota for logical space
|
||||
volumeRequest := &quobyteapi.CreateVolumeRequest{
|
||||
Name: provisioner.volume,
|
||||
RootUserID: provisioner.user,
|
||||
RootGroupID: provisioner.group,
|
||||
TenantID: provisioner.tenant,
|
||||
ConfigurationName: provisioner.config,
|
||||
}
|
||||
|
||||
quobyteClient := manager.createQuobyteClient()
|
||||
volumeUUID, err := quobyteClient.CreateVolume(volumeRequest)
|
||||
if err != nil {
|
||||
return &v1.QuobyteVolumeSource{}, volumeSize, err
|
||||
}
|
||||
|
||||
// Set Quota for Volume with specified byte size
|
||||
if createQuota {
|
||||
err = quobyteClient.SetVolumeQuota(volumeUUID, uint64(capacity.Value()))
|
||||
if err != nil {
|
||||
return &v1.QuobyteVolumeSource{}, volumeSize, err
|
||||
}
|
||||
}
|
||||
|
||||
glog.V(4).Infof("Created Quobyte volume %s", provisioner.volume)
|
||||
return &v1.QuobyteVolumeSource{
|
||||
Registry: provisioner.registry,
|
||||
Volume: provisioner.volume,
|
||||
User: provisioner.user,
|
||||
Group: provisioner.group,
|
||||
}, volumeSize, nil
|
||||
}
|
||||
|
||||
func (manager *quobyteVolumeManager) deleteVolume(deleter *quobyteVolumeDeleter) error {
|
||||
return manager.createQuobyteClient().DeleteVolumeByName(deleter.volume, deleter.tenant)
|
||||
}
|
||||
|
||||
func (manager *quobyteVolumeManager) createQuobyteClient() *quobyteapi.QuobyteClient {
|
||||
return quobyteapi.NewQuobyteClient(
|
||||
manager.config.quobyteAPIServer,
|
||||
manager.config.quobyteUser,
|
||||
manager.config.quobytePassword,
|
||||
)
|
||||
}
|
||||
|
||||
func (mounter *quobyteMounter) pluginDirIsMounted(pluginDir string) (bool, error) {
|
||||
mounts, err := mounter.mounter.List()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, mountPoint := range mounts {
|
||||
if strings.HasPrefix(mountPoint.Type, "quobyte") {
|
||||
continue
|
||||
}
|
||||
|
||||
if mountPoint.Path == pluginDir {
|
||||
glog.V(4).Infof("quobyte: found mountpoint %s in /proc/mounts", mountPoint.Path)
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (mounter *quobyteMounter) correctTraillingSlash(regStr string) string {
|
||||
return filepath.Clean(regStr) + string(os.PathSeparator)
|
||||
}
|
||||
|
||||
func validateRegistry(registry string) bool {
|
||||
if len(registry) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, hostPortPair := range strings.Split(registry, ",") {
|
||||
if _, _, err := net.SplitHostPort(hostPortPair); err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
Reference in New Issue
Block a user