vendor: bump to Kube 1.9/master
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
7076c73172
commit
7a675ccd92
202 changed files with 8543 additions and 7270 deletions
2
vendor/k8s.io/kubernetes/README.md
generated
vendored
2
vendor/k8s.io/kubernetes/README.md
generated
vendored
|
@ -1,6 +1,6 @@
|
|||
# Kubernetes
|
||||
|
||||
[![Submit Queue Widget]][Submit Queue] [![GoDoc Widget]][GoDoc]
|
||||
[![Submit Queue Widget]][Submit Queue] [![GoDoc Widget]][GoDoc] [](https://bestpractices.coreinfrastructure.org/projects/569)
|
||||
|
||||
<img src="https://github.com/kubernetes/kubernetes/raw/master/logo/logo.png" width="100">
|
||||
|
||||
|
|
6
vendor/k8s.io/kubernetes/pkg/api/annotation_key_constants.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/api/annotation_key_constants.go
generated
vendored
|
@ -45,12 +45,6 @@ const (
|
|||
// to one container of a pod.
|
||||
SeccompContainerAnnotationKeyPrefix string = "container.seccomp.security.alpha.kubernetes.io/"
|
||||
|
||||
// CreatedByAnnotation represents the key used to store the spec(json)
|
||||
// used to create the resource.
|
||||
// This field is deprecated in favor of ControllerRef (see #44407).
|
||||
// TODO(#50720): Remove this field in v1.9.
|
||||
CreatedByAnnotation = "kubernetes.io/created-by"
|
||||
|
||||
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
|
||||
// in the Annotations of a Node.
|
||||
PreferAvoidPodsAnnotationKey string = "scheduler.alpha.kubernetes.io/preferAvoidPods"
|
||||
|
|
5
vendor/k8s.io/kubernetes/pkg/api/helper/helpers.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/api/helper/helpers.go
generated
vendored
|
@ -265,6 +265,11 @@ func IsIntegerResourceName(str string) bool {
|
|||
return integerResources.Has(str) || IsExtendedResourceName(api.ResourceName(str))
|
||||
}
|
||||
|
||||
// Extended and HugePages resources
|
||||
func IsScalarResourceName(name api.ResourceName) bool {
|
||||
return IsExtendedResourceName(name) || IsHugePageResourceName(name)
|
||||
}
|
||||
|
||||
// this function aims to check if the service's ClusterIP is set or not
|
||||
// the objective is not to perform validation here
|
||||
func IsServiceIPSet(service *api.Service) bool {
|
||||
|
|
3
vendor/k8s.io/kubernetes/pkg/api/install/install.go
generated
vendored
3
vendor/k8s.io/kubernetes/pkg/api/install/install.go
generated
vendored
|
@ -24,11 +24,12 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Install(api.GroupFactoryRegistry, api.Registry, api.Scheme)
|
||||
Install(legacyscheme.GroupFactoryRegistry, legacyscheme.Registry, legacyscheme.Scheme)
|
||||
}
|
||||
|
||||
// Install registers the API group and adds types to a scheme
|
||||
|
|
46
vendor/k8s.io/kubernetes/pkg/api/legacyscheme/scheme.go
generated
vendored
Normal file
46
vendor/k8s.io/kubernetes/pkg/api/legacyscheme/scheme.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2014 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 legacyscheme
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
)
|
||||
|
||||
// GroupFactoryRegistry is the APIGroupFactoryRegistry (overlaps a bit with Registry, see comments in package for details)
|
||||
var GroupFactoryRegistry = make(announced.APIGroupFactoryRegistry)
|
||||
|
||||
// Registry is an instance of an API registry. This is an interim step to start removing the idea of a global
|
||||
// API registry.
|
||||
var Registry = registered.NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
|
||||
|
||||
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
|
||||
// NOTE: If you are copying this file to start a new api group, STOP! Copy the
|
||||
// extensions group instead. This Scheme is special and should appear ONLY in
|
||||
// the api group, unless you really know what you're doing.
|
||||
// TODO(lavalamp): make the above error impossible.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
// Codecs provides access to encoding and decoding for the scheme
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
|
||||
// ParameterCodec handles versioning of objects that are converted to query parameters.
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
25
vendor/k8s.io/kubernetes/pkg/api/register.go
generated
vendored
25
vendor/k8s.io/kubernetes/pkg/api/register.go
generated
vendored
|
@ -17,42 +17,17 @@ limitations under the License.
|
|||
package api
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
)
|
||||
|
||||
// GroupFactoryRegistry is the APIGroupFactoryRegistry (overlaps a bit with Registry, see comments in package for details)
|
||||
var GroupFactoryRegistry = make(announced.APIGroupFactoryRegistry)
|
||||
|
||||
// Registry is an instance of an API registry. This is an interim step to start removing the idea of a global
|
||||
// API registry.
|
||||
var Registry = registered.NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
|
||||
|
||||
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
|
||||
// NOTE: If you are copying this file to start a new api group, STOP! Copy the
|
||||
// extensions group instead. This Scheme is special and should appear ONLY in
|
||||
// the api group, unless you really know what you're doing.
|
||||
// TODO(lavalamp): make the above error impossible.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
// Codecs provides access to encoding and decoding for the scheme
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = ""
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// ParameterCodec handles versioning of objects that are converted to query parameters.
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
|
|
85
vendor/k8s.io/kubernetes/pkg/api/types.go
generated
vendored
85
vendor/k8s.io/kubernetes/pkg/api/types.go
generated
vendored
|
@ -343,7 +343,7 @@ type PersistentVolumeSource struct {
|
|||
NFS *NFSVolumeSource
|
||||
// RBD represents a Rados Block Device mount on the host that shares a pod's lifetime
|
||||
// +optional
|
||||
RBD *RBDVolumeSource
|
||||
RBD *RBDPersistentVolumeSource
|
||||
// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
|
||||
// +optional
|
||||
Quobyte *QuobyteVolumeSource
|
||||
|
@ -383,7 +383,7 @@ type PersistentVolumeSource struct {
|
|||
PortworxVolume *PortworxVolumeSource
|
||||
// ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
|
||||
// +optional
|
||||
ScaleIO *ScaleIOVolumeSource
|
||||
ScaleIO *ScaleIOPersistentVolumeSource
|
||||
// Local represents directly-attached storage with node affinity
|
||||
// +optional
|
||||
Local *LocalVolumeSource
|
||||
|
@ -1006,6 +1006,37 @@ type RBDVolumeSource struct {
|
|||
ReadOnly bool
|
||||
}
|
||||
|
||||
// Represents a Rados Block Device mount that lasts the lifetime of a pod.
|
||||
// RBD volumes support ownership management and SELinux relabeling.
|
||||
type RBDPersistentVolumeSource struct {
|
||||
// Required: CephMonitors is a collection of Ceph monitors
|
||||
CephMonitors []string
|
||||
// Required: RBDImage is the rados image name
|
||||
RBDImage string
|
||||
// Filesystem type to mount.
|
||||
// Must be a filesystem type supported by the host operating system.
|
||||
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
|
||||
// TODO: how do we prevent errors in the filesystem from compromising the machine
|
||||
// +optional
|
||||
FSType string
|
||||
// Optional: RadosPool is the rados pool name,default is rbd
|
||||
// +optional
|
||||
RBDPool string
|
||||
// Optional: RBDUser is the rados user name, default is admin
|
||||
// +optional
|
||||
RadosUser string
|
||||
// Optional: Keyring is the path to key ring for RBDUser, default is /etc/ceph/keyring
|
||||
// +optional
|
||||
Keyring string
|
||||
// Optional: SecretRef is reference to the authentication secret for User, default is empty.
|
||||
// +optional
|
||||
SecretRef *SecretReference
|
||||
// Optional: Defaults to false (read/write). ReadOnly here will force
|
||||
// the ReadOnly setting in VolumeMounts.
|
||||
// +optional
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
// Represents a cinder volume resource in Openstack. A Cinder volume
|
||||
// must exist before mounting to a container. The volume must also be
|
||||
// in the same region as the kubelet. Cinder volumes support ownership
|
||||
|
@ -1238,7 +1269,7 @@ type AzureDiskVolumeSource struct {
|
|||
// the ReadOnly setting in VolumeMounts.
|
||||
// +optional
|
||||
ReadOnly *bool
|
||||
// Expected values Shared: mulitple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared
|
||||
// Expected values Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared
|
||||
Kind *AzureDataDiskKind
|
||||
}
|
||||
|
||||
|
@ -1254,13 +1285,13 @@ type ScaleIOVolumeSource struct {
|
|||
// Flag to enable/disable SSL communication with Gateway, default false
|
||||
// +optional
|
||||
SSLEnabled bool
|
||||
// The name of the Protection Domain for the configured storage (defaults to "default").
|
||||
// The name of the ScaleIO Protection Domain for the configured storage.
|
||||
// +optional
|
||||
ProtectionDomain string
|
||||
// The Storage Pool associated with the protection domain (defaults to "default").
|
||||
// The ScaleIO Storage Pool associated with the protection domain.
|
||||
// +optional
|
||||
StoragePool string
|
||||
// Indicates whether the storage for a volume should be thick or thin (defaults to "thin").
|
||||
// Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
|
||||
// +optional
|
||||
StorageMode string
|
||||
// The name of a volume already created in the ScaleIO system
|
||||
|
@ -1277,6 +1308,42 @@ type ScaleIOVolumeSource struct {
|
|||
ReadOnly bool
|
||||
}
|
||||
|
||||
// ScaleIOPersistentVolumeSource represents a persistent ScaleIO volume that can be defined
|
||||
// by a an admin via a storage class, for instance.
|
||||
type ScaleIOPersistentVolumeSource struct {
|
||||
// The host address of the ScaleIO API Gateway.
|
||||
Gateway string
|
||||
// The name of the storage system as configured in ScaleIO.
|
||||
System string
|
||||
// SecretRef references to the secret for ScaleIO user and other
|
||||
// sensitive information. If this is not provided, Login operation will fail.
|
||||
SecretRef *SecretReference
|
||||
// Flag to enable/disable SSL communication with Gateway, default false
|
||||
// +optional
|
||||
SSLEnabled bool
|
||||
// The name of the ScaleIO Protection Domain for the configured storage.
|
||||
// +optional
|
||||
ProtectionDomain string
|
||||
// The ScaleIO Storage Pool associated with the protection domain.
|
||||
// +optional
|
||||
StoragePool string
|
||||
// Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
|
||||
// +optional
|
||||
StorageMode string
|
||||
// The name of a volume created in the ScaleIO system
|
||||
// that is associated with this volume source.
|
||||
VolumeName string
|
||||
// Filesystem type to mount.
|
||||
// Must be a filesystem type supported by the host operating system.
|
||||
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
|
||||
// +optional
|
||||
FSType string
|
||||
// Defaults to false (read/write). ReadOnly here will force
|
||||
// the ReadOnly setting in VolumeMounts.
|
||||
// +optional
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
// Represents a StorageOS persistent volume resource.
|
||||
type StorageOSVolumeSource struct {
|
||||
// VolumeName is the human-readable name of the StorageOS volume. Volume
|
||||
|
@ -2229,7 +2296,7 @@ type Taint struct {
|
|||
// TimeAdded represents the time at which the taint was added.
|
||||
// It is only written for NoExecute taints.
|
||||
// +optional
|
||||
TimeAdded metav1.Time
|
||||
TimeAdded *metav1.Time
|
||||
}
|
||||
|
||||
type TaintEffect string
|
||||
|
@ -3117,7 +3184,7 @@ type NodeConfigSource struct {
|
|||
type DaemonEndpoint struct {
|
||||
/*
|
||||
The port tag was not properly in quotes in earlier releases, so it must be
|
||||
uppercased for backwards compat (since it was falling back to var name of
|
||||
uppercase for backwards compatibility (since it was falling back to var name of
|
||||
'Port').
|
||||
*/
|
||||
|
||||
|
@ -4043,7 +4110,7 @@ const (
|
|||
// BasicAuthPasswordKey is the key of the password or token for SecretTypeBasicAuth secrets
|
||||
BasicAuthPasswordKey = "password"
|
||||
|
||||
// SecretTypeSSHAuth contains data needed for SSH authetication.
|
||||
// SecretTypeSSHAuth contains data needed for SSH authentication.
|
||||
//
|
||||
// Required field:
|
||||
// - Secret.Data["ssh-privatekey"] - private SSH key needed for authentication
|
||||
|
|
48
vendor/k8s.io/kubernetes/pkg/api/util/group_version.go
generated
vendored
48
vendor/k8s.io/kubernetes/pkg/api/util/group_version.go
generated
vendored
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// TODO: This GetVersion/GetGroup arrangement is temporary and will be replaced
|
||||
// with a GroupAndVersion type.
|
||||
package util
|
||||
|
||||
import "strings"
|
||||
|
||||
func GetVersion(groupVersion string) string {
|
||||
s := strings.Split(groupVersion, "/")
|
||||
if len(s) != 2 {
|
||||
// e.g. return "v1" for groupVersion="v1"
|
||||
return s[len(s)-1]
|
||||
}
|
||||
return s[1]
|
||||
}
|
||||
|
||||
func GetGroup(groupVersion string) string {
|
||||
s := strings.Split(groupVersion, "/")
|
||||
if len(s) == 1 {
|
||||
// e.g. return "" for groupVersion="v1"
|
||||
return ""
|
||||
}
|
||||
return s[0]
|
||||
}
|
||||
|
||||
// GetGroupVersion returns the "group/version". It returns "version" is if group
|
||||
// is empty. It returns "group/" if version is empty.
|
||||
func GetGroupVersion(group, version string) string {
|
||||
if len(group) == 0 {
|
||||
return version
|
||||
}
|
||||
return group + "/" + version
|
||||
}
|
20
vendor/k8s.io/kubernetes/pkg/api/v1/conversion.go
generated
vendored
20
vendor/k8s.io/kubernetes/pkg/api/v1/conversion.go
generated
vendored
|
@ -235,7 +235,9 @@ func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *v1.Replicatio
|
|||
|
||||
func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *v1.ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error {
|
||||
out.Replicas = *in.Replicas
|
||||
out.MinReadySeconds = in.MinReadySeconds
|
||||
if in.Selector != nil {
|
||||
out.Selector = new(metav1.LabelSelector)
|
||||
metav1.Convert_map_to_unversioned_LabelSelector(&in.Selector, out.Selector, s)
|
||||
}
|
||||
if in.Template != nil {
|
||||
|
@ -252,6 +254,15 @@ func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *v
|
|||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.AvailableReplicas = in.AvailableReplicas
|
||||
out.ObservedGeneration = in.ObservedGeneration
|
||||
for _, cond := range in.Conditions {
|
||||
out.Conditions = append(out.Conditions, extensions.ReplicaSetCondition{
|
||||
Type: extensions.ReplicaSetConditionType(cond.Type),
|
||||
Status: api.ConditionStatus(cond.Status),
|
||||
LastTransitionTime: cond.LastTransitionTime,
|
||||
Reason: cond.Reason,
|
||||
Message: cond.Message,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -294,6 +305,15 @@ func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *e
|
|||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.AvailableReplicas = in.AvailableReplicas
|
||||
out.ObservedGeneration = in.ObservedGeneration
|
||||
for _, cond := range in.Conditions {
|
||||
out.Conditions = append(out.Conditions, v1.ReplicationControllerCondition{
|
||||
Type: v1.ReplicationControllerConditionType(cond.Type),
|
||||
Status: v1.ConditionStatus(cond.Status),
|
||||
LastTransitionTime: cond.LastTransitionTime,
|
||||
Reason: cond.Reason,
|
||||
Message: cond.Message,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
23
vendor/k8s.io/kubernetes/pkg/api/v1/defaults.go
generated
vendored
23
vendor/k8s.io/kubernetes/pkg/api/v1/defaults.go
generated
vendored
|
@ -368,13 +368,28 @@ func SetDefaults_RBDVolumeSource(obj *v1.RBDVolumeSource) {
|
|||
}
|
||||
}
|
||||
|
||||
func SetDefaults_RBDPersistentVolumeSource(obj *v1.RBDPersistentVolumeSource) {
|
||||
if obj.RBDPool == "" {
|
||||
obj.RBDPool = "rbd"
|
||||
}
|
||||
if obj.RadosUser == "" {
|
||||
obj.RadosUser = "admin"
|
||||
}
|
||||
if obj.Keyring == "" {
|
||||
obj.Keyring = "/etc/ceph/keyring"
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_ScaleIOVolumeSource(obj *v1.ScaleIOVolumeSource) {
|
||||
if obj.ProtectionDomain == "" {
|
||||
obj.ProtectionDomain = "default"
|
||||
if obj.StorageMode == "" {
|
||||
obj.StorageMode = "ThinProvisioned"
|
||||
}
|
||||
if obj.StoragePool == "" {
|
||||
obj.StoragePool = "default"
|
||||
if obj.FSType == "" {
|
||||
obj.FSType = "xfs"
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_ScaleIOPersistentVolumeSource(obj *v1.ScaleIOPersistentVolumeSource) {
|
||||
if obj.StorageMode == "" {
|
||||
obj.StorageMode = "ThinProvisioned"
|
||||
}
|
||||
|
|
65
vendor/k8s.io/kubernetes/pkg/api/v1/generate.go
generated
vendored
65
vendor/k8s.io/kubernetes/pkg/api/v1/generate.go
generated
vendored
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/api/core/v1"
|
||||
|
||||
utilrand "k8s.io/apimachinery/pkg/util/rand"
|
||||
)
|
||||
|
||||
// NameGenerator generates names for objects. Some backends may have more information
|
||||
// available to guide selection of new names and this interface hides those details.
|
||||
type NameGenerator interface {
|
||||
// GenerateName generates a valid name from the base name, adding a random suffix to the
|
||||
// the base. If base is valid, the returned name must also be valid. The generator is
|
||||
// responsible for knowing the maximum valid name length.
|
||||
GenerateName(base string) string
|
||||
}
|
||||
|
||||
// GenerateName will resolve the object name of the provided v1.ObjectMeta to a generated version if
|
||||
// necessary. It expects that validation for v1.ObjectMeta has already completed (that Base is a
|
||||
// valid name) and that the NameGenerator generates a name that is also valid.
|
||||
func GenerateName(u NameGenerator, meta *v1.ObjectMeta) {
|
||||
if len(meta.GenerateName) == 0 || len(meta.Name) != 0 {
|
||||
return
|
||||
}
|
||||
meta.Name = u.GenerateName(meta.GenerateName)
|
||||
}
|
||||
|
||||
// simpleNameGenerator generates random names.
|
||||
type simpleNameGenerator struct{}
|
||||
|
||||
// SimpleNameGenerator is a generator that returns the name plus a random suffix of five alphanumerics
|
||||
// when a name is requested. The string is guaranteed to not exceed the length of a standard Kubernetes
|
||||
// name (63 characters)
|
||||
var SimpleNameGenerator NameGenerator = simpleNameGenerator{}
|
||||
|
||||
const (
|
||||
// TODO: make this flexible for non-core resources with alternate naming rules.
|
||||
maxNameLength = 63
|
||||
randomLength = 5
|
||||
maxGeneratedNameLength = maxNameLength - randomLength
|
||||
)
|
||||
|
||||
func (simpleNameGenerator) GenerateName(base string) string {
|
||||
if len(base) > maxGeneratedNameLength {
|
||||
base = base[:maxGeneratedNameLength]
|
||||
}
|
||||
return fmt.Sprintf("%s%s", base, utilrand.String(randomLength))
|
||||
}
|
8
vendor/k8s.io/kubernetes/pkg/api/v1/helper/helpers.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/api/v1/helper/helpers.go
generated
vendored
|
@ -88,12 +88,18 @@ func OpaqueIntResourceName(name string) v1.ResourceName {
|
|||
var overcommitBlacklist = sets.NewString(string(v1.ResourceNvidiaGPU))
|
||||
|
||||
// IsOvercommitAllowed returns true if the resource is in the default
|
||||
// namespace and not blacklisted.
|
||||
// namespace and not blacklisted and is not hugepages.
|
||||
func IsOvercommitAllowed(name v1.ResourceName) bool {
|
||||
return IsDefaultNamespaceResource(name) &&
|
||||
!IsHugePageResourceName(name) &&
|
||||
!overcommitBlacklist.Has(string(name))
|
||||
}
|
||||
|
||||
// Extended and Hugepages resources
|
||||
func IsScalarResourceName(name v1.ResourceName) bool {
|
||||
return IsExtendedResourceName(name) || IsHugePageResourceName(name)
|
||||
}
|
||||
|
||||
// this function aims to check if the service's ClusterIP is set or not
|
||||
// the objective is not to perform validation here
|
||||
func IsServiceIPSet(service *v1.Service) bool {
|
||||
|
|
88
vendor/k8s.io/kubernetes/pkg/api/v1/zz_generated.conversion.go
generated
vendored
88
vendor/k8s.io/kubernetes/pkg/api/v1/zz_generated.conversion.go
generated
vendored
|
@ -305,6 +305,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
|
|||
Convert_api_ProjectedVolumeSource_To_v1_ProjectedVolumeSource,
|
||||
Convert_v1_QuobyteVolumeSource_To_api_QuobyteVolumeSource,
|
||||
Convert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource,
|
||||
Convert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource,
|
||||
Convert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource,
|
||||
Convert_v1_RBDVolumeSource_To_api_RBDVolumeSource,
|
||||
Convert_api_RBDVolumeSource_To_v1_RBDVolumeSource,
|
||||
Convert_v1_RangeAllocation_To_api_RangeAllocation,
|
||||
|
@ -333,6 +335,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
|
|||
Convert_api_ResourceRequirements_To_v1_ResourceRequirements,
|
||||
Convert_v1_SELinuxOptions_To_api_SELinuxOptions,
|
||||
Convert_api_SELinuxOptions_To_v1_SELinuxOptions,
|
||||
Convert_v1_ScaleIOPersistentVolumeSource_To_api_ScaleIOPersistentVolumeSource,
|
||||
Convert_api_ScaleIOPersistentVolumeSource_To_v1_ScaleIOPersistentVolumeSource,
|
||||
Convert_v1_ScaleIOVolumeSource_To_api_ScaleIOVolumeSource,
|
||||
Convert_api_ScaleIOVolumeSource_To_v1_ScaleIOVolumeSource,
|
||||
Convert_v1_Secret_To_api_Secret,
|
||||
|
@ -3124,7 +3128,7 @@ func autoConvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *v1.
|
|||
out.HostPath = (*api.HostPathVolumeSource)(unsafe.Pointer(in.HostPath))
|
||||
out.Glusterfs = (*api.GlusterfsVolumeSource)(unsafe.Pointer(in.Glusterfs))
|
||||
out.NFS = (*api.NFSVolumeSource)(unsafe.Pointer(in.NFS))
|
||||
out.RBD = (*api.RBDVolumeSource)(unsafe.Pointer(in.RBD))
|
||||
out.RBD = (*api.RBDPersistentVolumeSource)(unsafe.Pointer(in.RBD))
|
||||
out.ISCSI = (*api.ISCSIVolumeSource)(unsafe.Pointer(in.ISCSI))
|
||||
out.Cinder = (*api.CinderVolumeSource)(unsafe.Pointer(in.Cinder))
|
||||
out.CephFS = (*api.CephFSPersistentVolumeSource)(unsafe.Pointer(in.CephFS))
|
||||
|
@ -3137,7 +3141,7 @@ func autoConvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *v1.
|
|||
out.AzureDisk = (*api.AzureDiskVolumeSource)(unsafe.Pointer(in.AzureDisk))
|
||||
out.PhotonPersistentDisk = (*api.PhotonPersistentDiskVolumeSource)(unsafe.Pointer(in.PhotonPersistentDisk))
|
||||
out.PortworxVolume = (*api.PortworxVolumeSource)(unsafe.Pointer(in.PortworxVolume))
|
||||
out.ScaleIO = (*api.ScaleIOVolumeSource)(unsafe.Pointer(in.ScaleIO))
|
||||
out.ScaleIO = (*api.ScaleIOPersistentVolumeSource)(unsafe.Pointer(in.ScaleIO))
|
||||
out.Local = (*api.LocalVolumeSource)(unsafe.Pointer(in.Local))
|
||||
out.StorageOS = (*api.StorageOSPersistentVolumeSource)(unsafe.Pointer(in.StorageOS))
|
||||
return nil
|
||||
|
@ -3154,7 +3158,7 @@ func autoConvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api
|
|||
out.HostPath = (*v1.HostPathVolumeSource)(unsafe.Pointer(in.HostPath))
|
||||
out.Glusterfs = (*v1.GlusterfsVolumeSource)(unsafe.Pointer(in.Glusterfs))
|
||||
out.NFS = (*v1.NFSVolumeSource)(unsafe.Pointer(in.NFS))
|
||||
out.RBD = (*v1.RBDVolumeSource)(unsafe.Pointer(in.RBD))
|
||||
out.RBD = (*v1.RBDPersistentVolumeSource)(unsafe.Pointer(in.RBD))
|
||||
out.Quobyte = (*v1.QuobyteVolumeSource)(unsafe.Pointer(in.Quobyte))
|
||||
out.ISCSI = (*v1.ISCSIVolumeSource)(unsafe.Pointer(in.ISCSI))
|
||||
out.FlexVolume = (*v1.FlexVolumeSource)(unsafe.Pointer(in.FlexVolume))
|
||||
|
@ -3167,7 +3171,7 @@ func autoConvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api
|
|||
out.AzureDisk = (*v1.AzureDiskVolumeSource)(unsafe.Pointer(in.AzureDisk))
|
||||
out.PhotonPersistentDisk = (*v1.PhotonPersistentDiskVolumeSource)(unsafe.Pointer(in.PhotonPersistentDisk))
|
||||
out.PortworxVolume = (*v1.PortworxVolumeSource)(unsafe.Pointer(in.PortworxVolume))
|
||||
out.ScaleIO = (*v1.ScaleIOVolumeSource)(unsafe.Pointer(in.ScaleIO))
|
||||
out.ScaleIO = (*v1.ScaleIOPersistentVolumeSource)(unsafe.Pointer(in.ScaleIO))
|
||||
out.Local = (*v1.LocalVolumeSource)(unsafe.Pointer(in.Local))
|
||||
out.StorageOS = (*v1.StorageOSPersistentVolumeSource)(unsafe.Pointer(in.StorageOS))
|
||||
return nil
|
||||
|
@ -4062,6 +4066,40 @@ func Convert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in *api.QuobyteVo
|
|||
return autoConvert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource(in *v1.RBDPersistentVolumeSource, out *api.RBDPersistentVolumeSource, s conversion.Scope) error {
|
||||
out.CephMonitors = *(*[]string)(unsafe.Pointer(&in.CephMonitors))
|
||||
out.RBDImage = in.RBDImage
|
||||
out.FSType = in.FSType
|
||||
out.RBDPool = in.RBDPool
|
||||
out.RadosUser = in.RadosUser
|
||||
out.Keyring = in.Keyring
|
||||
out.SecretRef = (*api.SecretReference)(unsafe.Pointer(in.SecretRef))
|
||||
out.ReadOnly = in.ReadOnly
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource is an autogenerated conversion function.
|
||||
func Convert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource(in *v1.RBDPersistentVolumeSource, out *api.RBDPersistentVolumeSource, s conversion.Scope) error {
|
||||
return autoConvert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource(in *api.RBDPersistentVolumeSource, out *v1.RBDPersistentVolumeSource, s conversion.Scope) error {
|
||||
out.CephMonitors = *(*[]string)(unsafe.Pointer(&in.CephMonitors))
|
||||
out.RBDImage = in.RBDImage
|
||||
out.FSType = in.FSType
|
||||
out.RBDPool = in.RBDPool
|
||||
out.RadosUser = in.RadosUser
|
||||
out.Keyring = in.Keyring
|
||||
out.SecretRef = (*v1.SecretReference)(unsafe.Pointer(in.SecretRef))
|
||||
out.ReadOnly = in.ReadOnly
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource is an autogenerated conversion function.
|
||||
func Convert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource(in *api.RBDPersistentVolumeSource, out *v1.RBDPersistentVolumeSource, s conversion.Scope) error {
|
||||
return autoConvert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *v1.RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error {
|
||||
out.CephMonitors = *(*[]string)(unsafe.Pointer(&in.CephMonitors))
|
||||
out.RBDImage = in.RBDImage
|
||||
|
@ -4458,6 +4496,44 @@ func Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out
|
|||
return autoConvert_api_SELinuxOptions_To_v1_SELinuxOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_ScaleIOPersistentVolumeSource_To_api_ScaleIOPersistentVolumeSource(in *v1.ScaleIOPersistentVolumeSource, out *api.ScaleIOPersistentVolumeSource, s conversion.Scope) error {
|
||||
out.Gateway = in.Gateway
|
||||
out.System = in.System
|
||||
out.SecretRef = (*api.SecretReference)(unsafe.Pointer(in.SecretRef))
|
||||
out.SSLEnabled = in.SSLEnabled
|
||||
out.ProtectionDomain = in.ProtectionDomain
|
||||
out.StoragePool = in.StoragePool
|
||||
out.StorageMode = in.StorageMode
|
||||
out.VolumeName = in.VolumeName
|
||||
out.FSType = in.FSType
|
||||
out.ReadOnly = in.ReadOnly
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_ScaleIOPersistentVolumeSource_To_api_ScaleIOPersistentVolumeSource is an autogenerated conversion function.
|
||||
func Convert_v1_ScaleIOPersistentVolumeSource_To_api_ScaleIOPersistentVolumeSource(in *v1.ScaleIOPersistentVolumeSource, out *api.ScaleIOPersistentVolumeSource, s conversion.Scope) error {
|
||||
return autoConvert_v1_ScaleIOPersistentVolumeSource_To_api_ScaleIOPersistentVolumeSource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_api_ScaleIOPersistentVolumeSource_To_v1_ScaleIOPersistentVolumeSource(in *api.ScaleIOPersistentVolumeSource, out *v1.ScaleIOPersistentVolumeSource, s conversion.Scope) error {
|
||||
out.Gateway = in.Gateway
|
||||
out.System = in.System
|
||||
out.SecretRef = (*v1.SecretReference)(unsafe.Pointer(in.SecretRef))
|
||||
out.SSLEnabled = in.SSLEnabled
|
||||
out.ProtectionDomain = in.ProtectionDomain
|
||||
out.StoragePool = in.StoragePool
|
||||
out.StorageMode = in.StorageMode
|
||||
out.VolumeName = in.VolumeName
|
||||
out.FSType = in.FSType
|
||||
out.ReadOnly = in.ReadOnly
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_api_ScaleIOPersistentVolumeSource_To_v1_ScaleIOPersistentVolumeSource is an autogenerated conversion function.
|
||||
func Convert_api_ScaleIOPersistentVolumeSource_To_v1_ScaleIOPersistentVolumeSource(in *api.ScaleIOPersistentVolumeSource, out *v1.ScaleIOPersistentVolumeSource, s conversion.Scope) error {
|
||||
return autoConvert_api_ScaleIOPersistentVolumeSource_To_v1_ScaleIOPersistentVolumeSource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_ScaleIOVolumeSource_To_api_ScaleIOVolumeSource(in *v1.ScaleIOVolumeSource, out *api.ScaleIOVolumeSource, s conversion.Scope) error {
|
||||
out.Gateway = in.Gateway
|
||||
out.System = in.System
|
||||
|
@ -5101,7 +5177,7 @@ func autoConvert_v1_Taint_To_api_Taint(in *v1.Taint, out *api.Taint, s conversio
|
|||
out.Key = in.Key
|
||||
out.Value = in.Value
|
||||
out.Effect = api.TaintEffect(in.Effect)
|
||||
out.TimeAdded = in.TimeAdded
|
||||
out.TimeAdded = (*meta_v1.Time)(unsafe.Pointer(in.TimeAdded))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -5114,7 +5190,7 @@ func autoConvert_api_Taint_To_v1_Taint(in *api.Taint, out *v1.Taint, s conversio
|
|||
out.Key = in.Key
|
||||
out.Value = in.Value
|
||||
out.Effect = v1.TaintEffect(in.Effect)
|
||||
out.TimeAdded = in.TimeAdded
|
||||
out.TimeAdded = (*meta_v1.Time)(unsafe.Pointer(in.TimeAdded))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
4
vendor/k8s.io/kubernetes/pkg/api/v1/zz_generated.defaults.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/api/v1/zz_generated.defaults.go
generated
vendored
|
@ -137,7 +137,7 @@ func SetObjectDefaults_PersistentVolume(in *v1.PersistentVolume) {
|
|||
SetDefaults_HostPathVolumeSource(in.Spec.PersistentVolumeSource.HostPath)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.RBD != nil {
|
||||
SetDefaults_RBDVolumeSource(in.Spec.PersistentVolumeSource.RBD)
|
||||
SetDefaults_RBDPersistentVolumeSource(in.Spec.PersistentVolumeSource.RBD)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.ISCSI != nil {
|
||||
SetDefaults_ISCSIVolumeSource(in.Spec.PersistentVolumeSource.ISCSI)
|
||||
|
@ -146,7 +146,7 @@ func SetObjectDefaults_PersistentVolume(in *v1.PersistentVolume) {
|
|||
SetDefaults_AzureDiskVolumeSource(in.Spec.PersistentVolumeSource.AzureDisk)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.ScaleIO != nil {
|
||||
SetDefaults_ScaleIOVolumeSource(in.Spec.PersistentVolumeSource.ScaleIO)
|
||||
SetDefaults_ScaleIOPersistentVolumeSource(in.Spec.PersistentVolumeSource.ScaleIO)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
vendor/k8s.io/kubernetes/pkg/api/validation/events.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/api/validation/events.go
generated
vendored
|
@ -25,7 +25,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
apiutil "k8s.io/kubernetes/pkg/api/util"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
)
|
||||
|
||||
// ValidateEvent makes sure that the event makes sense.
|
||||
|
@ -63,12 +63,16 @@ func ValidateEvent(event *api.Event) field.ErrorList {
|
|||
|
||||
// Check whether the kind in groupVersion is scoped at the root of the api hierarchy
|
||||
func isNamespacedKind(kind, groupVersion string) (bool, error) {
|
||||
group := apiutil.GetGroup(groupVersion)
|
||||
g, err := api.Registry.Group(group)
|
||||
gv, err := schema.ParseGroupVersion(groupVersion)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
restMapping, err := g.RESTMapper.RESTMapping(schema.GroupKind{Group: group, Kind: kind}, apiutil.GetVersion(groupVersion))
|
||||
g, err := legacyscheme.Registry.Group(gv.Group)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
restMapping, err := g.RESTMapper.RESTMapping(schema.GroupKind{Group: gv.Group, Kind: kind}, gv.Version)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
44
vendor/k8s.io/kubernetes/pkg/api/validation/validation.go
generated
vendored
44
vendor/k8s.io/kubernetes/pkg/api/validation/validation.go
generated
vendored
|
@ -45,6 +45,7 @@ import (
|
|||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/helper"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
apiservice "k8s.io/kubernetes/pkg/api/service"
|
||||
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
v1helper "k8s.io/kubernetes/pkg/api/v1/helper"
|
||||
|
@ -1087,6 +1088,17 @@ func validateRBDVolumeSource(rbd *api.RBDVolumeSource, fldPath *field.Path) fiel
|
|||
return allErrs
|
||||
}
|
||||
|
||||
func validateRBDPersistentVolumeSource(rbd *api.RBDPersistentVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(rbd.CephMonitors) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("monitors"), ""))
|
||||
}
|
||||
if len(rbd.RBDImage) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("image"), ""))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateCinderVolumeSource(cd *api.CinderVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(cd.VolumeID) == 0 {
|
||||
|
@ -1233,6 +1245,20 @@ func validateScaleIOVolumeSource(sio *api.ScaleIOVolumeSource, fldPath *field.Pa
|
|||
return allErrs
|
||||
}
|
||||
|
||||
func validateScaleIOPersistentVolumeSource(sio *api.ScaleIOPersistentVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if sio.Gateway == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("gateway"), ""))
|
||||
}
|
||||
if sio.System == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("system"), ""))
|
||||
}
|
||||
if sio.VolumeName == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("volumeName"), ""))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateLocalVolumeSource(ls *api.LocalVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if ls.Path == "" {
|
||||
|
@ -1379,7 +1405,7 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
|
|||
allErrs = append(allErrs, field.Forbidden(specPath.Child("rbd"), "may not specify more than 1 volume type"))
|
||||
} else {
|
||||
numVolumes++
|
||||
allErrs = append(allErrs, validateRBDVolumeSource(pv.Spec.RBD, specPath.Child("rbd"))...)
|
||||
allErrs = append(allErrs, validateRBDPersistentVolumeSource(pv.Spec.RBD, specPath.Child("rbd"))...)
|
||||
}
|
||||
}
|
||||
if pv.Spec.Quobyte != nil {
|
||||
|
@ -1477,7 +1503,7 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
|
|||
allErrs = append(allErrs, field.Forbidden(specPath.Child("scaleIO"), "may not specify more than 1 volume type"))
|
||||
} else {
|
||||
numVolumes++
|
||||
allErrs = append(allErrs, validateScaleIOVolumeSource(pv.Spec.ScaleIO, specPath.Child("scaleIO"))...)
|
||||
allErrs = append(allErrs, validateScaleIOPersistentVolumeSource(pv.Spec.ScaleIO, specPath.Child("scaleIO"))...)
|
||||
}
|
||||
}
|
||||
if pv.Spec.Local != nil {
|
||||
|
@ -1528,6 +1554,12 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
|
|||
func ValidatePersistentVolumeUpdate(newPv, oldPv *api.PersistentVolume) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = ValidatePersistentVolume(newPv)
|
||||
|
||||
// PersistentVolumeSource should be immutable after creation.
|
||||
if !apiequality.Semantic.DeepEqual(newPv.Spec.PersistentVolumeSource, oldPv.Spec.PersistentVolumeSource) {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "persistentvolumesource"), "is immutable after creation"))
|
||||
}
|
||||
|
||||
newPv.Status = oldPv.Status
|
||||
return allErrs
|
||||
}
|
||||
|
@ -1755,7 +1787,7 @@ func validateObjectFieldSelector(fs *api.ObjectFieldSelector, expressions *sets.
|
|||
} else if len(fs.FieldPath) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("fieldPath"), ""))
|
||||
} else {
|
||||
internalFieldPath, _, err := api.Scheme.ConvertFieldLabel(fs.APIVersion, "Pod", fs.FieldPath, "")
|
||||
internalFieldPath, _, err := legacyscheme.Scheme.ConvertFieldLabel(fs.APIVersion, "Pod", fs.FieldPath, "")
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("fieldPath"), fs.FieldPath, fmt.Sprintf("error converting fieldPath: %v", err)))
|
||||
} else if !expressions.Has(internalFieldPath) {
|
||||
|
@ -1923,7 +1955,11 @@ func ValidateVolumeMounts(mounts []api.VolumeMount, volumes sets.String, contain
|
|||
allErrs = append(allErrs, field.Invalid(idxPath.Child("mountPath"), mnt.MountPath, "must be unique"))
|
||||
}
|
||||
if !path.IsAbs(mnt.MountPath) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("mountPath"), mnt.MountPath, "must be an absolute path"))
|
||||
// also allow windows absolute path
|
||||
p := mnt.MountPath
|
||||
if len(p) < 2 || ((p[0] < 'A' || p[0] > 'Z') && (p[0] < 'a' || p[0] > 'z')) || p[1] != ':' {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("mountPath"), mnt.MountPath, "must be an absolute path"))
|
||||
}
|
||||
}
|
||||
mountpoints.Insert(mnt.MountPath)
|
||||
if len(mnt.SubPath) > 0 {
|
||||
|
|
77
vendor/k8s.io/kubernetes/pkg/api/zz_generated.deepcopy.go
generated
vendored
77
vendor/k8s.io/kubernetes/pkg/api/zz_generated.deepcopy.go
generated
vendored
|
@ -571,6 +571,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
in.(*QuobyteVolumeSource).DeepCopyInto(out.(*QuobyteVolumeSource))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&QuobyteVolumeSource{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*RBDPersistentVolumeSource).DeepCopyInto(out.(*RBDPersistentVolumeSource))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&RBDPersistentVolumeSource{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*RBDVolumeSource).DeepCopyInto(out.(*RBDVolumeSource))
|
||||
return nil
|
||||
|
@ -627,6 +631,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
in.(*SELinuxOptions).DeepCopyInto(out.(*SELinuxOptions))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&SELinuxOptions{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*ScaleIOPersistentVolumeSource).DeepCopyInto(out.(*ScaleIOPersistentVolumeSource))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&ScaleIOPersistentVolumeSource{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*ScaleIOVolumeSource).DeepCopyInto(out.(*ScaleIOVolumeSource))
|
||||
return nil
|
||||
|
@ -3747,7 +3755,7 @@ func (in *PersistentVolumeSource) DeepCopyInto(out *PersistentVolumeSource) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(RBDVolumeSource)
|
||||
*out = new(RBDPersistentVolumeSource)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
@ -3864,7 +3872,7 @@ func (in *PersistentVolumeSource) DeepCopyInto(out *PersistentVolumeSource) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(ScaleIOVolumeSource)
|
||||
*out = new(ScaleIOPersistentVolumeSource)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
@ -4815,6 +4823,36 @@ func (in *QuobyteVolumeSource) DeepCopy() *QuobyteVolumeSource {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RBDPersistentVolumeSource) DeepCopyInto(out *RBDPersistentVolumeSource) {
|
||||
*out = *in
|
||||
if in.CephMonitors != nil {
|
||||
in, out := &in.CephMonitors, &out.CephMonitors
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RBDPersistentVolumeSource.
|
||||
func (in *RBDPersistentVolumeSource) DeepCopy() *RBDPersistentVolumeSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RBDPersistentVolumeSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RBDVolumeSource) DeepCopyInto(out *RBDVolumeSource) {
|
||||
*out = *in
|
||||
|
@ -5196,6 +5234,31 @@ func (in *SELinuxOptions) DeepCopy() *SELinuxOptions {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScaleIOPersistentVolumeSource) DeepCopyInto(out *ScaleIOPersistentVolumeSource) {
|
||||
*out = *in
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScaleIOPersistentVolumeSource.
|
||||
func (in *ScaleIOPersistentVolumeSource) DeepCopy() *ScaleIOPersistentVolumeSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScaleIOPersistentVolumeSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScaleIOVolumeSource) DeepCopyInto(out *ScaleIOVolumeSource) {
|
||||
*out = *in
|
||||
|
@ -5903,7 +5966,15 @@ func (in *TCPSocketAction) DeepCopy() *TCPSocketAction {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Taint) DeepCopyInto(out *Taint) {
|
||||
*out = *in
|
||||
in.TimeAdded.DeepCopyInto(&out.TimeAdded)
|
||||
if in.TimeAdded != nil {
|
||||
in, out := &in.TimeAdded, &out.TimeAdded
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.Time)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
2
vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go
generated
vendored
|
@ -43,7 +43,7 @@ var (
|
|||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
// Adds the list of known types to the given scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
// TODO this gets cleaned up when the types are fixed
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
|
|
4
vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go
generated
vendored
|
@ -759,7 +759,7 @@ type IngressBackend struct {
|
|||
// +genclient:method=UpdateScale,verb=update,subresource=scale,input=Scale,result=Scale
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ReplicaSet represents the configuration of a replica set.
|
||||
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
|
||||
type ReplicaSet struct {
|
||||
metav1.TypeMeta
|
||||
// +optional
|
||||
|
@ -1010,7 +1010,7 @@ type SELinuxStrategyOptions struct {
|
|||
// Rule is the strategy that will dictate the allowable labels that may be set.
|
||||
Rule SELinuxStrategy
|
||||
// seLinuxOptions required to run as; required for MustRunAs
|
||||
// More info: https://git.k8s.io/community/contributors/design-proposals/security_context.md
|
||||
// More info: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#selinux
|
||||
// +optional
|
||||
SELinuxOptions *api.SELinuxOptions
|
||||
}
|
||||
|
|
4
vendor/k8s.io/kubernetes/pkg/cloudprovider/README.md
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/cloudprovider/README.md
generated
vendored
|
@ -4,7 +4,7 @@
|
|||
The mechanism for supporting cloud providers is currently in transition: the original method of implementing cloud provider-specific functionality within the main kubernetes tree (here) is no longer advised; however, the proposed solution is still in development.
|
||||
|
||||
#### Guidance for potential cloud providers:
|
||||
* Support for cloud providers is currently in a state of flux. Background information on motivation and the proposal for improving is in the github [proposal](https://git.k8s.io/community/contributors/design-proposals/cloud-provider-refactoring.md).
|
||||
* Support for cloud providers is currently in a state of flux. Background information on motivation and the proposal for improving is in the github [proposal](https://git.k8s.io/community/contributors/design-proposals/cloud-provider/cloud-provider-refactoring.md).
|
||||
* In support of this plan, a new cloud-controller-manager binary was added in 1.6. This was the first of several steps (see the proposal for more information).
|
||||
* Attempts to contribute new cloud providers or (to a lesser extent) persistent volumes to the core repo will likely meet with some pushback from reviewers/approvers.
|
||||
* It is understood that this is an unfortunate situation in which 'the old way is no longer supported but the new way is not ready yet', but the initial path is unsustainable, and contributors are encouraged to participate in the implementation of the proposed long-term solution, as there is risk that PRs for new cloud providers here will not be approved.
|
||||
|
@ -13,4 +13,4 @@ The mechanism for supporting cloud providers is currently in transition: the or
|
|||
#### Some additional context on status / direction:
|
||||
* 1.6 added a new cloud-controller-manager binary that may be used for testing the new out-of-core cloudprovider flow.
|
||||
* Setting cloud-provider=external allows for creation of a separate controller-manager binary
|
||||
* 1.7 adds [extensible admission control](https://git.k8s.io/community/contributors/design-proposals/admission_control_extension.md), further enabling topology customization.
|
||||
* 1.7 adds [extensible admission control](https://git.k8s.io/community/contributors/design-proposals/api-machinery/admission_control_extension.md), further enabling topology customization.
|
||||
|
|
1
vendor/k8s.io/kubernetes/pkg/cloudprovider/cloud.go
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/cloudprovider/cloud.go
generated
vendored
|
@ -176,6 +176,7 @@ type Routes interface {
|
|||
var (
|
||||
InstanceNotFound = errors.New("instance not found")
|
||||
DiskNotFound = errors.New("disk is not found")
|
||||
NotImplemented = errors.New("unimplemented")
|
||||
)
|
||||
|
||||
// Zone represents the location of a particular machine.
|
||||
|
|
3
vendor/k8s.io/kubernetes/pkg/controller/client_builder.go
generated
vendored
3
vendor/k8s.io/kubernetes/pkg/controller/client_builder.go
generated
vendored
|
@ -35,6 +35,7 @@ import (
|
|||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
@ -237,7 +238,7 @@ func (b SAControllerClientBuilder) getAuthenticatedConfig(sa *v1.ServiceAccount,
|
|||
// If we couldn't run the token review, the API might be disabled or we might not have permission.
|
||||
// Try to make a request to /apis with the token. If we get a 401 we should consider the token invalid.
|
||||
clientConfigCopy := *clientConfig
|
||||
clientConfigCopy.NegotiatedSerializer = api.Codecs
|
||||
clientConfigCopy.NegotiatedSerializer = legacyscheme.Codecs
|
||||
client, err := restclient.UnversionedRESTClientFor(&clientConfigCopy)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
|
|
44
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
44
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
|
@ -38,10 +38,8 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
ref "k8s.io/client-go/tools/reference"
|
||||
"k8s.io/client-go/util/integer"
|
||||
clientretry "k8s.io/client-go/util/retry"
|
||||
_ "k8s.io/kubernetes/pkg/api/install"
|
||||
|
@ -474,29 +472,12 @@ func getPodsFinalizers(template *v1.PodTemplateSpec) []string {
|
|||
return desiredFinalizers
|
||||
}
|
||||
|
||||
func getPodsAnnotationSet(template *v1.PodTemplateSpec, object runtime.Object) (labels.Set, error) {
|
||||
func getPodsAnnotationSet(template *v1.PodTemplateSpec) labels.Set {
|
||||
desiredAnnotations := make(labels.Set)
|
||||
for k, v := range template.Annotations {
|
||||
desiredAnnotations[k] = v
|
||||
}
|
||||
createdByRef, err := ref.GetReference(scheme.Scheme, object)
|
||||
if err != nil {
|
||||
return desiredAnnotations, fmt.Errorf("unable to get controller reference: %v", err)
|
||||
}
|
||||
|
||||
// TODO: this code was not safe previously - as soon as new code came along that switched to v2, old clients
|
||||
// would be broken upon reading it. This is explicitly hardcoded to v1 to guarantee predictable deployment.
|
||||
// We need to consistently handle this case of annotation versioning.
|
||||
codec := scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion)
|
||||
|
||||
createdByRefJson, err := runtime.Encode(codec, &v1.SerializedReference{
|
||||
Reference: *createdByRef,
|
||||
})
|
||||
if err != nil {
|
||||
return desiredAnnotations, fmt.Errorf("unable to serialize controller reference: %v", err)
|
||||
}
|
||||
desiredAnnotations[v1.CreatedByAnnotation] = string(createdByRefJson)
|
||||
return desiredAnnotations, nil
|
||||
return desiredAnnotations
|
||||
}
|
||||
|
||||
func getPodsPrefix(controllerName string) string {
|
||||
|
@ -546,17 +527,14 @@ func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *v
|
|||
}
|
||||
|
||||
func (r RealPodControl) PatchPod(namespace, name string, data []byte) error {
|
||||
_, err := r.KubeClient.Core().Pods(namespace).Patch(name, types.StrategicMergePatchType, data)
|
||||
_, err := r.KubeClient.CoreV1().Pods(namespace).Patch(name, types.StrategicMergePatchType, data)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetPodFromTemplate(template *v1.PodTemplateSpec, parentObject runtime.Object, controllerRef *metav1.OwnerReference) (*v1.Pod, error) {
|
||||
desiredLabels := getPodsLabelSet(template)
|
||||
desiredFinalizers := getPodsFinalizers(template)
|
||||
desiredAnnotations, err := getPodsAnnotationSet(template, parentObject)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
desiredAnnotations := getPodsAnnotationSet(template)
|
||||
accessor, err := meta.Accessor(parentObject)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parentObject does not have ObjectMeta, %v", err)
|
||||
|
@ -589,7 +567,7 @@ func (r RealPodControl) createPods(nodeName, namespace string, template *v1.PodT
|
|||
if labels.Set(pod.Labels).AsSelectorPreValidated().Empty() {
|
||||
return fmt.Errorf("unable to create pods, no labels")
|
||||
}
|
||||
if newPod, err := r.KubeClient.Core().Pods(namespace).Create(pod); err != nil {
|
||||
if newPod, err := r.KubeClient.CoreV1().Pods(namespace).Create(pod); err != nil {
|
||||
r.Recorder.Eventf(object, v1.EventTypeWarning, FailedCreatePodReason, "Error creating: %v", err)
|
||||
return err
|
||||
} else {
|
||||
|
@ -610,7 +588,7 @@ func (r RealPodControl) DeletePod(namespace string, podID string, object runtime
|
|||
return fmt.Errorf("object does not have ObjectMeta, %v", err)
|
||||
}
|
||||
glog.V(2).Infof("Controller %v deleting pod %v/%v", accessor.GetName(), namespace, podID)
|
||||
if err := r.KubeClient.Core().Pods(namespace).Delete(podID, nil); err != nil {
|
||||
if err := r.KubeClient.CoreV1().Pods(namespace).Delete(podID, nil); err != nil {
|
||||
r.Recorder.Eventf(object, v1.EventTypeWarning, FailedDeletePodReason, "Error deleting: %v", err)
|
||||
return fmt.Errorf("unable to delete pods: %v", err)
|
||||
} else {
|
||||
|
@ -925,10 +903,10 @@ func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taints ...*v
|
|||
// First we try getting node from the API server cache, as it's cheaper. If it fails
|
||||
// we get it from etcd to be sure to have fresh data.
|
||||
if firstTry {
|
||||
oldNode, err = c.Core().Nodes().Get(nodeName, metav1.GetOptions{ResourceVersion: "0"})
|
||||
oldNode, err = c.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{ResourceVersion: "0"})
|
||||
firstTry = false
|
||||
} else {
|
||||
oldNode, err = c.Core().Nodes().Get(nodeName, metav1.GetOptions{})
|
||||
oldNode, err = c.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -982,10 +960,10 @@ func RemoveTaintOffNode(c clientset.Interface, nodeName string, node *v1.Node, t
|
|||
// First we try getting node from the API server cache, as it's cheaper. If it fails
|
||||
// we get it from etcd to be sure to have fresh data.
|
||||
if firstTry {
|
||||
oldNode, err = c.Core().Nodes().Get(nodeName, metav1.GetOptions{ResourceVersion: "0"})
|
||||
oldNode, err = c.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{ResourceVersion: "0"})
|
||||
firstTry = false
|
||||
} else {
|
||||
oldNode, err = c.Core().Nodes().Get(nodeName, metav1.GetOptions{})
|
||||
oldNode, err = c.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -1030,7 +1008,7 @@ func PatchNodeTaints(c clientset.Interface, nodeName string, oldNode *v1.Node, n
|
|||
return fmt.Errorf("failed to create patch for node %q: %v", nodeName, err)
|
||||
}
|
||||
|
||||
_, err = c.Core().Nodes().Patch(string(nodeName), types.StrategicMergePatchType, patchBytes)
|
||||
_, err = c.CoreV1().Nodes().Patch(string(nodeName), types.StrategicMergePatchType, patchBytes)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
9
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
|
@ -163,6 +163,12 @@ const (
|
|||
//
|
||||
// Enable pods to consume pre-allocated huge pages of varying page sizes
|
||||
HugePages utilfeature.Feature = "HugePages"
|
||||
|
||||
// owner @brendandburns
|
||||
// alpha: v1.8
|
||||
//
|
||||
// Enable nodes to exclude themselves from service load balancers
|
||||
ServiceNodeExclusion utilfeature.Feature = "ServiceNodeExclusion"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -194,6 +200,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
|
|||
MountPropagation: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
ExpandPersistentVolumes: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
CPUManager: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
ServiceNodeExclusion: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
|
||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
@ -201,7 +208,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
|
|||
genericfeatures.AdvancedAuditing: {Default: true, PreRelease: utilfeature.Beta},
|
||||
genericfeatures.APIResponseCompression: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
genericfeatures.Initializers: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
genericfeatures.APIListChunking: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
genericfeatures.APIListChunking: {Default: true, PreRelease: utilfeature.Beta},
|
||||
|
||||
// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
|
1558
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime/api.pb.go
generated
vendored
1558
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime/api.pb.go
generated
vendored
File diff suppressed because it is too large
Load diff
52
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime/api.proto
generated
vendored
52
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime/api.proto
generated
vendored
|
@ -331,6 +331,8 @@ message RemovePodSandboxResponse {}
|
|||
message PodSandboxStatusRequest {
|
||||
// ID of the PodSandbox for which to retrieve status.
|
||||
string pod_sandbox_id = 1;
|
||||
// Verbose indicates whether to return extra information about the pod sandbox.
|
||||
bool verbose = 2;
|
||||
}
|
||||
|
||||
// PodSandboxNetworkStatus is the status of the network for a PodSandbox.
|
||||
|
@ -382,6 +384,11 @@ message PodSandboxStatus {
|
|||
message PodSandboxStatusResponse {
|
||||
// Status of the PodSandbox.
|
||||
PodSandboxStatus status = 1;
|
||||
// Info is extra information of the PodSandbox. The key could be abitrary string, and
|
||||
// value should be in json format. The information could include anything useful for
|
||||
// debug, e.g. network namespace for linux container based container runtime.
|
||||
// It should only be returned non-empty when Verbose is true.
|
||||
map<string, string> info = 2;
|
||||
}
|
||||
|
||||
// PodSandboxStateValue is the wrapper of PodSandboxState.
|
||||
|
@ -523,6 +530,7 @@ message LinuxContainerSecurityContext {
|
|||
repeated int64 supplemental_groups = 8;
|
||||
// AppArmor profile for the container, candidate values are:
|
||||
// * runtime/default: equivalent to not specifying a profile.
|
||||
// * unconfined: no profiles are loaded
|
||||
// * localhost/<profile_name>: profile loaded on the node
|
||||
// (localhost) by name. The possible profile names are detailed at
|
||||
// http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference
|
||||
|
@ -746,6 +754,8 @@ message ListContainersResponse {
|
|||
message ContainerStatusRequest {
|
||||
// ID of the container for which to retrieve status.
|
||||
string container_id = 1;
|
||||
// Verbose indicates whether to return extra information about the container.
|
||||
bool verbose = 2;
|
||||
}
|
||||
|
||||
// ContainerStatus represents the status of a container.
|
||||
|
@ -790,6 +800,11 @@ message ContainerStatus {
|
|||
message ContainerStatusResponse {
|
||||
// Status of the container.
|
||||
ContainerStatus status = 1;
|
||||
// Info is extra information of the Container. The key could be abitrary string, and
|
||||
// value should be in json format. The information could include anything useful for
|
||||
// debug, e.g. pid for linux container based container runtime.
|
||||
// It should only be returned non-empty when Verbose is true.
|
||||
map<string, string> info = 2;
|
||||
}
|
||||
|
||||
message UpdateContainerResourcesRequest {
|
||||
|
@ -827,7 +842,17 @@ message ExecRequest {
|
|||
// Whether to exec the command in a TTY.
|
||||
bool tty = 3;
|
||||
// Whether to stream stdin.
|
||||
// One of `stdin`, `stdout`, and `stderr` MUST be true.
|
||||
bool stdin = 4;
|
||||
// Whether to stream stdout.
|
||||
// One of `stdin`, `stdout`, and `stderr` MUST be true.
|
||||
bool stdout = 5;
|
||||
// Whether to stream stderr.
|
||||
// One of `stdin`, `stdout`, and `stderr` MUST be true.
|
||||
// If `tty` is true, `stderr` MUST be false. Multiplexing is not supported
|
||||
// in this case. The output of stdout and stderr will be combined to a
|
||||
// single stream.
|
||||
bool stderr = 6;
|
||||
}
|
||||
|
||||
message ExecResponse {
|
||||
|
@ -839,10 +864,20 @@ message AttachRequest {
|
|||
// ID of the container to which to attach.
|
||||
string container_id = 1;
|
||||
// Whether to stream stdin.
|
||||
// One of `stdin`, `stdout`, and `stderr` MUST be true.
|
||||
bool stdin = 2;
|
||||
// Whether the process being attached is running in a TTY.
|
||||
// This must match the TTY setting in the ContainerConfig.
|
||||
bool tty = 3;
|
||||
// Whether to stream stdout.
|
||||
// One of `stdin`, `stdout`, and `stderr` MUST be true.
|
||||
bool stdout = 4;
|
||||
// Whether to stream stderr.
|
||||
// One of `stdin`, `stdout`, and `stderr` MUST be true.
|
||||
// If `tty` is true, `stderr` MUST be false. Multiplexing is not supported
|
||||
// in this case. The output of stdout and stderr will be combined to a
|
||||
// single stream.
|
||||
bool stderr = 5;
|
||||
}
|
||||
|
||||
message AttachResponse {
|
||||
|
@ -899,11 +934,18 @@ message ListImagesResponse {
|
|||
message ImageStatusRequest {
|
||||
// Spec of the image.
|
||||
ImageSpec image = 1;
|
||||
// Verbose indicates whether to return extra information about the image.
|
||||
bool verbose = 2;
|
||||
}
|
||||
|
||||
message ImageStatusResponse {
|
||||
// Status of the image.
|
||||
Image image = 1;
|
||||
// Info is extra information of the Image. The key could be abitrary string, and
|
||||
// value should be in json format. The information could include anything useful
|
||||
// for debug, e.g. image config for oci image based container runtime.
|
||||
// It should only be returned non-empty when Verbose is true.
|
||||
map<string, string> info = 2;
|
||||
}
|
||||
|
||||
// AuthConfig contains authorization information for connecting to a registry.
|
||||
|
@ -986,11 +1028,19 @@ message RuntimeStatus {
|
|||
repeated RuntimeCondition conditions = 1;
|
||||
}
|
||||
|
||||
message StatusRequest {}
|
||||
message StatusRequest {
|
||||
// Verbose indicates whether to return extra information about the runtime.
|
||||
bool verbose = 1;
|
||||
}
|
||||
|
||||
message StatusResponse {
|
||||
// Status of the Runtime.
|
||||
RuntimeStatus status = 1;
|
||||
// Info is extra information of the Runtime. The key could be abitrary string, and
|
||||
// value should be in json format. The information could include anything useful for
|
||||
// debug, e.g. plugins used by the container runtime.
|
||||
// It should only be returned non-empty when Verbose is true.
|
||||
map<string, string> info = 2;
|
||||
}
|
||||
|
||||
message ImageFsInfoRequest {}
|
||||
|
|
2
vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go
generated
vendored
|
@ -48,7 +48,7 @@ type HandlerRunner interface {
|
|||
type RuntimeHelper interface {
|
||||
GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (contOpts *RunContainerOptions, useClusterFirstPolicy bool, err error)
|
||||
GetClusterDNS(pod *v1.Pod) (dnsServers []string, dnsSearches []string, useClusterFirstPolicy bool, err error)
|
||||
// GetPodCgroupParent returns the the CgroupName identifer, and its literal cgroupfs form on the host
|
||||
// GetPodCgroupParent returns the CgroupName identifer, and its literal cgroupfs form on the host
|
||||
// of a pod.
|
||||
GetPodCgroupParent(pod *v1.Pod) string
|
||||
GetPodDir(podUID types.UID) string
|
||||
|
|
4
vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go
generated
vendored
|
@ -21,7 +21,7 @@ import (
|
|||
|
||||
"k8s.io/api/core/v1"
|
||||
ref "k8s.io/client-go/tools/reference"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
)
|
||||
|
||||
var ImplicitContainerPrefix string = "implicitly required container "
|
||||
|
@ -39,7 +39,7 @@ func GenerateContainerRef(pod *v1.Pod, container *v1.Container) (*v1.ObjectRefer
|
|||
// start (like the pod infra container). This is not a good way, ugh.
|
||||
fieldPath = ImplicitContainerPrefix + container.Name
|
||||
}
|
||||
ref, err := ref.GetPartialReference(api.Scheme, pod, fieldPath)
|
||||
ref, err := ref.GetPartialReference(legacyscheme.Scheme, pod, fieldPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
5
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go
generated
vendored
|
@ -127,9 +127,8 @@ type Runtime interface {
|
|||
// DirectStreamingRuntime is the interface implemented by runtimes for which the streaming calls
|
||||
// (exec/attach/port-forward) should be served directly by the Kubelet.
|
||||
type DirectStreamingRuntime interface {
|
||||
// Runs the command in the container of the specified pod using nsenter.
|
||||
// Attaches the processes stdin, stdout, and stderr. Optionally uses a
|
||||
// tty.
|
||||
// Runs the command in the container of the specified pod. Attaches
|
||||
// the processes stdin, stdout, and stderr. Optionally uses a tty.
|
||||
ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error
|
||||
// Forward the specified port from the specified pod to the stream.
|
||||
PortForward(pod *Pod, port int32, stream io.ReadWriteCloser) error
|
||||
|
|
5
vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/hostport_manager.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/hostport_manager.go
generated
vendored
|
@ -177,11 +177,6 @@ func (hm *hostportManager) Remove(id string, podPortMapping *PodPortMapping) (er
|
|||
chainsToRemove := []utiliptables.Chain{}
|
||||
for _, pm := range hostportMappings {
|
||||
chainsToRemove = append(chainsToRemove, getHostportChain(id, pm))
|
||||
|
||||
// To preserve backward compatibility for k8s 1.5 or earlier.
|
||||
// Need to remove hostport chains added by hostportSyncer if there is any
|
||||
// TODO: remove this in 1.7
|
||||
chainsToRemove = append(chainsToRemove, hostportChainName(pm, getPodFullName(podPortMapping)))
|
||||
}
|
||||
|
||||
// remove rules that consists of target chains
|
||||
|
|
2
vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/hostport_syncer.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/hostport_syncer.go
generated
vendored
|
@ -64,7 +64,7 @@ func (hp *hostport) String() string {
|
|||
return fmt.Sprintf("%s:%d", hp.protocol, hp.port)
|
||||
}
|
||||
|
||||
//openPodHostports opens all hostport for pod and returns the map of hostport and socket
|
||||
// openHostports opens all hostport for pod and returns the map of hostport and socket
|
||||
func (h *hostportSyncer) openHostports(podHostportMapping *PodPortMapping) error {
|
||||
var retErr error
|
||||
ports := make(map[hostport]closeable)
|
||||
|
|
50
vendor/k8s.io/kubernetes/pkg/kubelet/server/streaming/server.go
generated
vendored
50
vendor/k8s.io/kubernetes/pkg/kubelet/server/streaming/server.go
generated
vendored
|
@ -158,9 +158,24 @@ type server struct {
|
|||
server *http.Server
|
||||
}
|
||||
|
||||
func (s *server) GetExec(req *runtimeapi.ExecRequest) (*runtimeapi.ExecResponse, error) {
|
||||
func validateExecRequest(req *runtimeapi.ExecRequest) error {
|
||||
if req.ContainerId == "" {
|
||||
return nil, grpc.Errorf(codes.InvalidArgument, "missing required container_id")
|
||||
return grpc.Errorf(codes.InvalidArgument, "missing required container_id")
|
||||
}
|
||||
if req.Tty && req.Stderr {
|
||||
// If TTY is set, stderr cannot be true because multiplexing is not
|
||||
// supported.
|
||||
return grpc.Errorf(codes.InvalidArgument, "tty and stderr cannot both be true")
|
||||
}
|
||||
if !req.Stdin && !req.Stdout && !req.Stderr {
|
||||
return grpc.Errorf(codes.InvalidArgument, "one of stdin, stdout, or stderr must be set")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) GetExec(req *runtimeapi.ExecRequest) (*runtimeapi.ExecResponse, error) {
|
||||
if err := validateExecRequest(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token, err := s.cache.Insert(req)
|
||||
if err != nil {
|
||||
|
@ -171,9 +186,24 @@ func (s *server) GetExec(req *runtimeapi.ExecRequest) (*runtimeapi.ExecResponse,
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (s *server) GetAttach(req *runtimeapi.AttachRequest) (*runtimeapi.AttachResponse, error) {
|
||||
func validateAttachRequest(req *runtimeapi.AttachRequest) error {
|
||||
if req.ContainerId == "" {
|
||||
return nil, grpc.Errorf(codes.InvalidArgument, "missing required container_id")
|
||||
return grpc.Errorf(codes.InvalidArgument, "missing required container_id")
|
||||
}
|
||||
if req.Tty && req.Stderr {
|
||||
// If TTY is set, stderr cannot be true because multiplexing is not
|
||||
// supported.
|
||||
return grpc.Errorf(codes.InvalidArgument, "tty and stderr cannot both be true")
|
||||
}
|
||||
if !req.Stdin && !req.Stdout && !req.Stderr {
|
||||
return grpc.Errorf(codes.InvalidArgument, "one of stdin, stdout, and stderr must be set")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) GetAttach(req *runtimeapi.AttachRequest) (*runtimeapi.AttachResponse, error) {
|
||||
if err := validateAttachRequest(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token, err := s.cache.Insert(req)
|
||||
if err != nil {
|
||||
|
@ -239,8 +269,8 @@ func (s *server) serveExec(req *restful.Request, resp *restful.Response) {
|
|||
|
||||
streamOpts := &remotecommandserver.Options{
|
||||
Stdin: exec.Stdin,
|
||||
Stdout: true,
|
||||
Stderr: !exec.Tty,
|
||||
Stdout: exec.Stdout,
|
||||
Stderr: exec.Stderr,
|
||||
TTY: exec.Tty,
|
||||
}
|
||||
|
||||
|
@ -273,8 +303,8 @@ func (s *server) serveAttach(req *restful.Request, resp *restful.Response) {
|
|||
|
||||
streamOpts := &remotecommandserver.Options{
|
||||
Stdin: attach.Stdin,
|
||||
Stdout: true,
|
||||
Stderr: !attach.Tty,
|
||||
Stdout: attach.Stdout,
|
||||
Stderr: attach.Stderr,
|
||||
TTY: attach.Tty,
|
||||
}
|
||||
remotecommandserver.ServeAttach(
|
||||
|
@ -332,11 +362,11 @@ var _ remotecommandserver.Attacher = &criAdapter{}
|
|||
var _ portforward.PortForwarder = &criAdapter{}
|
||||
|
||||
func (a *criAdapter) ExecInContainer(podName string, podUID types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error {
|
||||
return a.Exec(container, cmd, in, out, err, tty, resize)
|
||||
return a.Runtime.Exec(container, cmd, in, out, err, tty, resize)
|
||||
}
|
||||
|
||||
func (a *criAdapter) AttachContainer(podName string, podUID types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error {
|
||||
return a.Attach(container, in, out, err, tty, resize)
|
||||
return a.Runtime.Attach(container, in, out, err, tty, resize)
|
||||
}
|
||||
|
||||
func (a *criAdapter) PortForward(podName string, podUID types.UID, port int32, stream io.ReadWriteCloser) error {
|
||||
|
|
71
vendor/k8s.io/kubernetes/pkg/proxy/iptables/proxier.go
generated
vendored
71
vendor/k8s.io/kubernetes/pkg/proxy/iptables/proxier.go
generated
vendored
|
@ -47,6 +47,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/proxy"
|
||||
"k8s.io/kubernetes/pkg/proxy/healthcheck"
|
||||
"k8s.io/kubernetes/pkg/proxy/metrics"
|
||||
utilproxy "k8s.io/kubernetes/pkg/proxy/util"
|
||||
"k8s.io/kubernetes/pkg/util/async"
|
||||
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
|
||||
|
@ -166,12 +167,9 @@ type endpointsInfo struct {
|
|||
chainName utiliptables.Chain
|
||||
}
|
||||
|
||||
// Returns just the IP part of the endpoint.
|
||||
// IPPart returns just the IP part of the endpoint.
|
||||
func (e *endpointsInfo) IPPart() string {
|
||||
if index := strings.Index(e.endpoint, ":"); index != -1 {
|
||||
return e.endpoint[0:index]
|
||||
}
|
||||
return e.endpoint
|
||||
return utilproxy.IPPart(e.endpoint)
|
||||
}
|
||||
|
||||
// Returns the endpoint chain name for a given endpointsInfo.
|
||||
|
@ -320,12 +318,14 @@ func (scm *serviceChangeMap) update(namespacedName *types.NamespacedName, previo
|
|||
func (sm *proxyServiceMap) merge(other proxyServiceMap) sets.String {
|
||||
existingPorts := sets.NewString()
|
||||
for svcPortName, info := range other {
|
||||
port := strconv.Itoa(info.port)
|
||||
clusterIPPort := net.JoinHostPort(info.clusterIP.String(), port)
|
||||
existingPorts.Insert(svcPortName.Port)
|
||||
_, exists := (*sm)[svcPortName]
|
||||
if !exists {
|
||||
glog.V(1).Infof("Adding new service port %q at %s:%d/%s", svcPortName, info.clusterIP, info.port, info.protocol)
|
||||
glog.V(1).Infof("Adding new service port %q at %s/%s", svcPortName, clusterIPPort, info.protocol)
|
||||
} else {
|
||||
glog.V(1).Infof("Updating existing service port %q at %s:%d/%s", svcPortName, info.clusterIP, info.port, info.protocol)
|
||||
glog.V(1).Infof("Updating existing service port %q at %s/%s", svcPortName, clusterIPPort, info.protocol)
|
||||
}
|
||||
(*sm)[svcPortName] = info
|
||||
}
|
||||
|
@ -798,11 +798,15 @@ func getLocalIPs(endpointsMap proxyEndpointsMap) map[types.NamespacedName]sets.S
|
|||
for svcPortName := range endpointsMap {
|
||||
for _, ep := range endpointsMap[svcPortName] {
|
||||
if ep.isLocal {
|
||||
nsn := svcPortName.NamespacedName
|
||||
if localIPs[nsn] == nil {
|
||||
localIPs[nsn] = sets.NewString()
|
||||
// If the endpoint has a bad format, ipPart() will log an
|
||||
// error and ep.IPPart() will return a null string.
|
||||
if ip := ep.IPPart(); ip != "" {
|
||||
nsn := svcPortName.NamespacedName
|
||||
if localIPs[nsn] == nil {
|
||||
localIPs[nsn] = sets.NewString()
|
||||
}
|
||||
localIPs[nsn].Insert(ip)
|
||||
}
|
||||
localIPs[nsn].Insert(ep.IPPart()) // just the IP part
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -924,10 +928,7 @@ type endpointServicePair struct {
|
|||
}
|
||||
|
||||
func (esp *endpointServicePair) IPPart() string {
|
||||
if index := strings.Index(esp.endpoint, ":"); index != -1 {
|
||||
return esp.endpoint[0:index]
|
||||
}
|
||||
return esp.endpoint
|
||||
return utilproxy.IPPart(esp.endpoint)
|
||||
}
|
||||
|
||||
// After a UDP endpoint has been removed, we must flush any pending conntrack entries to it, or else we
|
||||
|
@ -936,7 +937,7 @@ func (esp *endpointServicePair) IPPart() string {
|
|||
func (proxier *Proxier) deleteEndpointConnections(connectionMap map[endpointServicePair]bool) {
|
||||
for epSvcPair := range connectionMap {
|
||||
if svcInfo, ok := proxier.serviceMap[epSvcPair.servicePortName]; ok && svcInfo.protocol == api.ProtocolUDP {
|
||||
endpointIP := epSvcPair.endpoint[0:strings.Index(epSvcPair.endpoint, ":")]
|
||||
endpointIP := utilproxy.IPPart(epSvcPair.endpoint)
|
||||
err := utilproxy.ClearUDPConntrackForPeers(proxier.exec, svcInfo.clusterIP.String(), endpointIP)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to delete %s endpoint connections, error: %v", epSvcPair.servicePortName.String(), err)
|
||||
|
@ -954,7 +955,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
SyncProxyRulesLatency.Observe(sinceInMicroseconds(start))
|
||||
metrics.SyncProxyRulesLatency.Observe(metrics.SinceInMicroseconds(start))
|
||||
glog.V(4).Infof("syncProxyRules took %v", time.Since(start))
|
||||
}()
|
||||
// don't sync rules till we've received services and endpoints
|
||||
|
@ -1162,7 +1163,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
"-A", string(kubeServicesChain),
|
||||
"-m", "comment", "--comment", fmt.Sprintf(`"%s cluster IP"`, svcNameString),
|
||||
"-m", protocol, "-p", protocol,
|
||||
"-d", fmt.Sprintf("%s/32", svcInfo.clusterIP.String()),
|
||||
"-d", utilproxy.ToCIDR(svcInfo.clusterIP),
|
||||
"--dport", strconv.Itoa(svcInfo.port),
|
||||
)
|
||||
if proxier.masqueradeAll {
|
||||
|
@ -1216,7 +1217,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
"-A", string(kubeServicesChain),
|
||||
"-m", "comment", "--comment", fmt.Sprintf(`"%s external IP"`, svcNameString),
|
||||
"-m", protocol, "-p", protocol,
|
||||
"-d", fmt.Sprintf("%s/32", externalIP),
|
||||
"-d", utilproxy.ToCIDR(net.ParseIP(externalIP)),
|
||||
"--dport", strconv.Itoa(svcInfo.port),
|
||||
)
|
||||
// We have to SNAT packets to external IPs.
|
||||
|
@ -1242,7 +1243,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
"-A", string(kubeServicesChain),
|
||||
"-m", "comment", "--comment", fmt.Sprintf(`"%s has no endpoints"`, svcNameString),
|
||||
"-m", protocol, "-p", protocol,
|
||||
"-d", fmt.Sprintf("%s/32", externalIP),
|
||||
"-d", utilproxy.ToCIDR(net.ParseIP(externalIP)),
|
||||
"--dport", strconv.Itoa(svcInfo.port),
|
||||
"-j", "REJECT",
|
||||
)
|
||||
|
@ -1268,7 +1269,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
"-A", string(kubeServicesChain),
|
||||
"-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcNameString),
|
||||
"-m", protocol, "-p", protocol,
|
||||
"-d", fmt.Sprintf("%s/32", ingress.IP),
|
||||
"-d", utilproxy.ToCIDR(net.ParseIP(ingress.IP)),
|
||||
"--dport", strconv.Itoa(svcInfo.port),
|
||||
)
|
||||
// jump to service firewall chain
|
||||
|
@ -1306,7 +1307,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
// loadbalancer's backend hosts. In this case, request will not hit the loadbalancer but loop back directly.
|
||||
// Need to add the following rule to allow request on host.
|
||||
if allowFromNode {
|
||||
writeLine(proxier.natRules, append(args, "-s", fmt.Sprintf("%s/32", ingress.IP), "-j", string(chosenChain))...)
|
||||
writeLine(proxier.natRules, append(args, "-s", utilproxy.ToCIDR(net.ParseIP(ingress.IP)), "-j", string(chosenChain))...)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1342,7 +1343,8 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
// This is very low impact. The NodePort range is intentionally obscure, and unlikely to actually collide with real Services.
|
||||
// This only affects UDP connections, which are not common.
|
||||
// See issue: https://github.com/kubernetes/kubernetes/issues/49881
|
||||
err := utilproxy.ClearUDPConntrackForPort(proxier.exec, lp.Port)
|
||||
isIPv6 := utilproxy.IsIPv6(svcInfo.clusterIP)
|
||||
err := utilproxy.ClearUDPConntrackForPort(proxier.exec, lp.Port, isIPv6)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to clear udp conntrack for port %d, error: %v", lp.Port, err)
|
||||
}
|
||||
|
@ -1389,7 +1391,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
"-A", string(kubeServicesChain),
|
||||
"-m", "comment", "--comment", fmt.Sprintf(`"%s has no endpoints"`, svcNameString),
|
||||
"-m", protocol, "-p", protocol,
|
||||
"-d", fmt.Sprintf("%s/32", svcInfo.clusterIP.String()),
|
||||
"-d", utilproxy.ToCIDR(svcInfo.clusterIP),
|
||||
"--dport", strconv.Itoa(svcInfo.port),
|
||||
"-j", "REJECT",
|
||||
)
|
||||
|
@ -1433,6 +1435,11 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
// Now write loadbalancing & DNAT rules.
|
||||
n := len(endpointChains)
|
||||
for i, endpointChain := range endpointChains {
|
||||
epIP := endpoints[i].IPPart()
|
||||
if epIP == "" {
|
||||
// Error parsing this endpoint has been logged. Skip to next endpoint.
|
||||
continue
|
||||
}
|
||||
// Balancing rules in the per-service chain.
|
||||
args = append(args[:0], []string{
|
||||
"-A", string(svcChain),
|
||||
|
@ -1456,7 +1463,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
)
|
||||
// Handle traffic that loops back to the originator with SNAT.
|
||||
writeLine(proxier.natRules, append(args,
|
||||
"-s", fmt.Sprintf("%s/32", endpoints[i].IPPart()),
|
||||
"-s", utilproxy.ToCIDR(net.ParseIP(epIP)),
|
||||
"-j", string(KubeMarkMasqChain))...)
|
||||
// Update client-affinity lists.
|
||||
if svcInfo.sessionAffinityType == api.ServiceAffinityClientIP {
|
||||
|
@ -1571,20 +1578,6 @@ func (proxier *Proxier) syncProxyRules() {
|
|||
err = proxier.iptables.RestoreAll(proxier.iptablesData.Bytes(), utiliptables.NoFlushTables, utiliptables.RestoreCounters)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to execute iptables-restore: %v", err)
|
||||
// ~rough approximation, assume ~100 chars per line
|
||||
// we log first 1000 bytes, but full list at higher levels
|
||||
rules := proxier.iptablesData.Bytes()
|
||||
if len(rules) > 1000 {
|
||||
abridgedRules := rules[:1000]
|
||||
if glog.V(4) {
|
||||
glog.V(4).Infof("Rules:\n%s", rules)
|
||||
} else {
|
||||
glog.V(2).Infof("Rules (abridged):\n%s", abridgedRules)
|
||||
}
|
||||
} else {
|
||||
glog.V(2).Infof("Rules:\n%s", rules)
|
||||
}
|
||||
|
||||
// Revert new local ports.
|
||||
glog.V(2).Infof("Closing local ports after iptables-restore failure")
|
||||
utilproxy.RevertPorts(replacementPortsMap, proxier.portsMap)
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package iptables
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
@ -26,6 +26,7 @@ import (
|
|||
const kubeProxySubsystem = "kubeproxy"
|
||||
|
||||
var (
|
||||
// SyncProxyRulesLatency is the latency of one round of kube-proxy syncing proxy rules.
|
||||
SyncProxyRulesLatency = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: kubeProxySubsystem,
|
||||
|
@ -38,13 +39,14 @@ var (
|
|||
|
||||
var registerMetricsOnce sync.Once
|
||||
|
||||
// RegisterMetrics registers sync proxy rules latency metrics
|
||||
func RegisterMetrics() {
|
||||
registerMetricsOnce.Do(func() {
|
||||
prometheus.MustRegister(SyncProxyRulesLatency)
|
||||
})
|
||||
}
|
||||
|
||||
// Gets the time since the specified start in microseconds.
|
||||
func sinceInMicroseconds(start time.Time) float64 {
|
||||
// SinceInMicroseconds gets the time since the specified start in microseconds.
|
||||
func SinceInMicroseconds(start time.Time) float64 {
|
||||
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
|
||||
}
|
30
vendor/k8s.io/kubernetes/pkg/proxy/util/conntrack.go
generated
vendored
30
vendor/k8s.io/kubernetes/pkg/proxy/util/conntrack.go
generated
vendored
|
@ -18,6 +18,7 @@ package util
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -28,10 +29,27 @@ import (
|
|||
|
||||
const noConnectionToDelete = "0 flow entries have been deleted"
|
||||
|
||||
// DeleteServiceConnections uses the conntrack tool to delete the conntrack entries
|
||||
func IsIPv6(netIP net.IP) bool {
|
||||
return netIP != nil && netIP.To4() == nil
|
||||
}
|
||||
|
||||
func IsIPv6String(ip string) bool {
|
||||
netIP := net.ParseIP(ip)
|
||||
return IsIPv6(netIP)
|
||||
}
|
||||
|
||||
func parametersWithFamily(isIPv6 bool, parameters ...string) []string {
|
||||
if isIPv6 {
|
||||
parameters = append(parameters, "-f", "ipv6")
|
||||
}
|
||||
return parameters
|
||||
}
|
||||
|
||||
// ClearUDPConntrackForIP uses the conntrack tool to delete the conntrack entries
|
||||
// for the UDP connections specified by the given service IP
|
||||
func ClearUDPConntrackForIP(execer exec.Interface, ip string) error {
|
||||
err := ExecConntrackTool(execer, "-D", "--orig-dst", ip, "-p", "udp")
|
||||
parameters := parametersWithFamily(IsIPv6String(ip), "-D", "--orig-dst", ip, "-p", "udp")
|
||||
err := ExecConntrackTool(execer, parameters...)
|
||||
if err != nil && !strings.Contains(err.Error(), noConnectionToDelete) {
|
||||
// TODO: Better handling for deletion failure. When failure occur, stale udp connection may not get flushed.
|
||||
// These stale udp connection will keep black hole traffic. Making this a best effort operation for now, since it
|
||||
|
@ -60,11 +78,12 @@ func ExecConntrackTool(execer exec.Interface, parameters ...string) error {
|
|||
// The solution is clearing the conntrack. Known issues:
|
||||
// https://github.com/docker/docker/issues/8795
|
||||
// https://github.com/kubernetes/kubernetes/issues/31983
|
||||
func ClearUDPConntrackForPort(execer exec.Interface, port int) error {
|
||||
func ClearUDPConntrackForPort(execer exec.Interface, port int, isIPv6 bool) error {
|
||||
if port <= 0 {
|
||||
return fmt.Errorf("Wrong port number. The port number must be greater than zero")
|
||||
}
|
||||
err := ExecConntrackTool(execer, "-D", "-p", "udp", "--dport", strconv.Itoa(port))
|
||||
parameters := parametersWithFamily(isIPv6, "-D", "-p", "udp", "--dport", strconv.Itoa(port))
|
||||
err := ExecConntrackTool(execer, parameters...)
|
||||
if err != nil && !strings.Contains(err.Error(), noConnectionToDelete) {
|
||||
return fmt.Errorf("error deleting conntrack entries for UDP port: %d, error: %v", port, err)
|
||||
}
|
||||
|
@ -74,7 +93,8 @@ func ClearUDPConntrackForPort(execer exec.Interface, port int) error {
|
|||
// ClearUDPConntrackForPeers uses the conntrack tool to delete the conntrack entries
|
||||
// for the UDP connections specified by the {origin, dest} IP pair.
|
||||
func ClearUDPConntrackForPeers(execer exec.Interface, origin, dest string) error {
|
||||
err := ExecConntrackTool(execer, "-D", "--orig-dst", origin, "--dst-nat", dest, "-p", "udp")
|
||||
parameters := parametersWithFamily(IsIPv6String(origin), "-D", "--orig-dst", origin, "--dst-nat", dest, "-p", "udp")
|
||||
err := ExecConntrackTool(execer, parameters...)
|
||||
if err != nil && !strings.Contains(err.Error(), noConnectionToDelete) {
|
||||
// TODO: Better handling for deletion failure. When failure occur, stale udp connection may not get flushed.
|
||||
// These stale udp connection will keep black hole traffic. Making this a best effort operation for now, since it
|
||||
|
|
51
vendor/k8s.io/kubernetes/pkg/proxy/util/endpoints.go
generated
vendored
Normal file
51
vendor/k8s.io/kubernetes/pkg/proxy/util/endpoints.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright 2017 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// IPPart returns just the IP part of an IP or IP:port or endpoint string. If the IP
|
||||
// part is an IPv6 address enclosed in brackets (e.g. "[fd00:1::5]:9999"),
|
||||
// then the brackets are stripped as well.
|
||||
func IPPart(s string) string {
|
||||
if ip := net.ParseIP(s); ip != nil {
|
||||
// IP address without port
|
||||
return s
|
||||
}
|
||||
// Must be IP:port
|
||||
ip, _, err := net.SplitHostPort(s)
|
||||
if err != nil {
|
||||
glog.Errorf("Error parsing '%s': %v", s, err)
|
||||
return ""
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
// ToCIDR returns a host address of the form <ip-address>/32 for
|
||||
// IPv4 and <ip-address>/128 for IPv6
|
||||
func ToCIDR(ip net.IP) string {
|
||||
len := 32
|
||||
if ip.To4() == nil {
|
||||
len = 128
|
||||
}
|
||||
return fmt.Sprintf("%s/%d", ip.String(), len)
|
||||
}
|
5
vendor/k8s.io/kubernetes/pkg/proxy/util/port.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/proxy/util/port.go
generated
vendored
|
@ -18,6 +18,8 @@ package util
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@ -37,7 +39,8 @@ type LocalPort struct {
|
|||
}
|
||||
|
||||
func (lp *LocalPort) String() string {
|
||||
return fmt.Sprintf("%q (%s:%d/%s)", lp.Description, lp.IP, lp.Port, lp.Protocol)
|
||||
ipPort := net.JoinHostPort(lp.IP, strconv.Itoa(lp.Port))
|
||||
return fmt.Sprintf("%q (%s/%s)", lp.Description, ipPort, lp.Protocol)
|
||||
}
|
||||
|
||||
// Closeable is an interface around closing an port.
|
||||
|
|
7
vendor/k8s.io/kubernetes/pkg/security/apparmor/helpers.go
generated
vendored
7
vendor/k8s.io/kubernetes/pkg/security/apparmor/helpers.go
generated
vendored
|
@ -35,13 +35,16 @@ const (
|
|||
ProfileRuntimeDefault = "runtime/default"
|
||||
// The prefix for specifying profiles loaded on the node.
|
||||
ProfileNamePrefix = "localhost/"
|
||||
|
||||
// Unconfined profile
|
||||
ProfileNameUnconfined = "unconfined"
|
||||
)
|
||||
|
||||
// Checks whether app armor is required for pod to be run.
|
||||
func isRequired(pod *v1.Pod) bool {
|
||||
for key := range pod.Annotations {
|
||||
for key, value := range pod.Annotations {
|
||||
if strings.HasPrefix(key, ContainerAnnotationKeyPrefix) {
|
||||
return true
|
||||
return value != ProfileNameUnconfined
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
|
2
vendor/k8s.io/kubernetes/pkg/security/apparmor/validate.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/security/apparmor/validate.go
generated
vendored
|
@ -136,7 +136,7 @@ func validateProfile(profile string, loadedProfiles map[string]bool) error {
|
|||
}
|
||||
|
||||
func ValidateProfileFormat(profile string) error {
|
||||
if profile == "" || profile == ProfileRuntimeDefault {
|
||||
if profile == "" || profile == ProfileRuntimeDefault || profile == ProfileNameUnconfined {
|
||||
return nil
|
||||
}
|
||||
if !strings.HasPrefix(profile, ProfileNamePrefix) {
|
||||
|
|
6
vendor/k8s.io/kubernetes/pkg/util/dbus/fake_dbus.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/util/dbus/fake_dbus.go
generated
vendored
|
@ -18,6 +18,7 @@ package dbus
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
godbus "github.com/godbus/dbus"
|
||||
)
|
||||
|
@ -30,6 +31,7 @@ type DBusFake struct {
|
|||
|
||||
// DBusFakeConnection represents a fake D-Bus connection
|
||||
type DBusFakeConnection struct {
|
||||
lock sync.Mutex
|
||||
busObject *fakeObject
|
||||
objects map[string]*fakeObject
|
||||
signalHandlers []chan<- *godbus.Signal
|
||||
|
@ -88,6 +90,8 @@ func (conn *DBusFakeConnection) Object(name, path string) Object {
|
|||
|
||||
// Signal is part of the Connection interface
|
||||
func (conn *DBusFakeConnection) Signal(ch chan<- *godbus.Signal) {
|
||||
conn.lock.Lock()
|
||||
defer conn.lock.Unlock()
|
||||
for i := range conn.signalHandlers {
|
||||
if conn.signalHandlers[i] == ch {
|
||||
conn.signalHandlers = append(conn.signalHandlers[:i], conn.signalHandlers[i+1:]...)
|
||||
|
@ -109,6 +113,8 @@ func (conn *DBusFakeConnection) AddObject(name, path string, handler DBusFakeHan
|
|||
|
||||
// EmitSignal emits a signal on conn
|
||||
func (conn *DBusFakeConnection) EmitSignal(name, path, iface, signal string, args ...interface{}) {
|
||||
conn.lock.Lock()
|
||||
defer conn.lock.Unlock()
|
||||
sig := &godbus.Signal{
|
||||
Sender: name,
|
||||
Path: godbus.ObjectPath(path),
|
||||
|
|
90
vendor/k8s.io/kubernetes/pkg/util/iptables/iptables.go
generated
vendored
90
vendor/k8s.io/kubernetes/pkg/util/iptables/iptables.go
generated
vendored
|
@ -94,10 +94,12 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
cmdIPTablesSave string = "iptables-save"
|
||||
cmdIPTablesRestore string = "iptables-restore"
|
||||
cmdIPTables string = "iptables"
|
||||
cmdIp6tables string = "ip6tables"
|
||||
cmdIPTablesSave string = "iptables-save"
|
||||
cmdIPTablesRestore string = "iptables-restore"
|
||||
cmdIPTables string = "iptables"
|
||||
cmdIP6TablesRestore string = "ip6tables-restore"
|
||||
cmdIP6TablesSave string = "ip6tables-save"
|
||||
cmdIP6Tables string = "ip6tables"
|
||||
)
|
||||
|
||||
// Option flag for Restore
|
||||
|
@ -116,9 +118,11 @@ const NoFlushTables FlushFlag = false
|
|||
// (test whether a rule exists).
|
||||
const MinCheckVersion = "1.4.11"
|
||||
|
||||
// Minimum iptables versions supporting the -w and -w2 flags
|
||||
const MinWaitVersion = "1.4.20"
|
||||
const MinWait2Version = "1.4.22"
|
||||
// Minimum iptables versions supporting the -w and -w<seconds> flags
|
||||
const WaitMinVersion = "1.4.20"
|
||||
const WaitSecondsMinVersion = "1.4.22"
|
||||
const WaitString = "-w"
|
||||
const WaitSecondsString = "-w5"
|
||||
|
||||
const LockfilePath16x = "/run/xtables.lock"
|
||||
|
||||
|
@ -140,7 +144,7 @@ type runner struct {
|
|||
// newInternal returns a new Interface which will exec iptables, and allows the
|
||||
// caller to change the iptables-restore lockfile path
|
||||
func newInternal(exec utilexec.Interface, dbus utildbus.Interface, protocol Protocol, lockfilePath string) Interface {
|
||||
vstring, err := getIPTablesVersionString(exec)
|
||||
vstring, err := getIPTablesVersionString(exec, protocol)
|
||||
if err != nil {
|
||||
glog.Warningf("Error checking iptables version, assuming version at least %s: %v", MinCheckVersion, err)
|
||||
vstring = MinCheckVersion
|
||||
|
@ -156,7 +160,7 @@ func newInternal(exec utilexec.Interface, dbus utildbus.Interface, protocol Prot
|
|||
protocol: protocol,
|
||||
hasCheck: getIPTablesHasCheckCommand(vstring),
|
||||
waitFlag: getIPTablesWaitFlag(vstring),
|
||||
restoreWaitFlag: getIPTablesRestoreWaitFlag(exec),
|
||||
restoreWaitFlag: getIPTablesRestoreWaitFlag(exec, protocol),
|
||||
lockfilePath: lockfilePath,
|
||||
}
|
||||
// TODO this needs to be moved to a separate Start() or Run() function so that New() has zero side
|
||||
|
@ -207,7 +211,7 @@ func (runner *runner) connectToFirewallD() {
|
|||
|
||||
// GetVersion returns the version string.
|
||||
func (runner *runner) GetVersion() (string, error) {
|
||||
return getIPTablesVersionString(runner.exec)
|
||||
return getIPTablesVersionString(runner.exec, runner.protocol)
|
||||
}
|
||||
|
||||
// EnsureChain is part of Interface.
|
||||
|
@ -310,9 +314,10 @@ func (runner *runner) SaveInto(table Table, buffer *bytes.Buffer) error {
|
|||
defer runner.mu.Unlock()
|
||||
|
||||
// run and return
|
||||
iptablesSaveCmd := iptablesSaveCommand(runner.protocol)
|
||||
args := []string{"-t", string(table)}
|
||||
glog.V(4).Infof("running iptables-save %v", args)
|
||||
cmd := runner.exec.Command(cmdIPTablesSave, args...)
|
||||
glog.V(4).Infof("running %s %v", iptablesSaveCmd, args)
|
||||
cmd := runner.exec.Command(iptablesSaveCmd, args...)
|
||||
// Since CombinedOutput() doesn't support redirecting it to a buffer,
|
||||
// we need to workaround it by redirecting stdout and stderr to buffer
|
||||
// and explicitly calling Run() [CombinedOutput() underneath itself
|
||||
|
@ -370,8 +375,9 @@ func (runner *runner) restoreInternal(args []string, data []byte, flush FlushFla
|
|||
|
||||
// run the command and return the output or an error including the output and error
|
||||
fullArgs := append(runner.restoreWaitFlag, args...)
|
||||
glog.V(4).Infof("running iptables-restore %v", fullArgs)
|
||||
cmd := runner.exec.Command(cmdIPTablesRestore, fullArgs...)
|
||||
iptablesRestoreCmd := iptablesRestoreCommand(runner.protocol)
|
||||
glog.V(4).Infof("running %s %v", iptablesRestoreCmd, fullArgs)
|
||||
cmd := runner.exec.Command(iptablesRestoreCmd, fullArgs...)
|
||||
cmd.SetStdin(bytes.NewBuffer(data))
|
||||
b, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
|
@ -380,17 +386,32 @@ func (runner *runner) restoreInternal(args []string, data []byte, flush FlushFla
|
|||
return nil
|
||||
}
|
||||
|
||||
func (runner *runner) iptablesCommand() string {
|
||||
if runner.IsIpv6() {
|
||||
return cmdIp6tables
|
||||
func iptablesSaveCommand(protocol Protocol) string {
|
||||
if protocol == ProtocolIpv6 {
|
||||
return cmdIP6TablesSave
|
||||
} else {
|
||||
return cmdIPTablesSave
|
||||
}
|
||||
}
|
||||
|
||||
func iptablesRestoreCommand(protocol Protocol) string {
|
||||
if protocol == ProtocolIpv6 {
|
||||
return cmdIP6TablesRestore
|
||||
} else {
|
||||
return cmdIPTablesRestore
|
||||
}
|
||||
}
|
||||
|
||||
func iptablesCommand(protocol Protocol) string {
|
||||
if protocol == ProtocolIpv6 {
|
||||
return cmdIP6Tables
|
||||
} else {
|
||||
return cmdIPTables
|
||||
}
|
||||
}
|
||||
|
||||
func (runner *runner) run(op operation, args []string) ([]byte, error) {
|
||||
iptablesCmd := runner.iptablesCommand()
|
||||
|
||||
iptablesCmd := iptablesCommand(runner.protocol)
|
||||
fullArgs := append(runner.waitFlag, string(op))
|
||||
fullArgs = append(fullArgs, args...)
|
||||
glog.V(5).Infof("running iptables %s %v", string(op), args)
|
||||
|
@ -418,8 +439,9 @@ func trimhex(s string) string {
|
|||
// Present for compatibility with <1.4.11 versions of iptables. This is full
|
||||
// of hack and half-measures. We should nix this ASAP.
|
||||
func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...string) (bool, error) {
|
||||
glog.V(1).Infof("running iptables-save -t %s", string(table))
|
||||
out, err := runner.exec.Command(cmdIPTablesSave, "-t", string(table)).CombinedOutput()
|
||||
iptablesSaveCmd := iptablesSaveCommand(runner.protocol)
|
||||
glog.V(1).Infof("running %s -t %s", iptablesSaveCmd, string(table))
|
||||
out, err := runner.exec.Command(iptablesSaveCmd, "-t", string(table)).CombinedOutput()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error checking rule: %v", err)
|
||||
}
|
||||
|
@ -517,32 +539,33 @@ func getIPTablesWaitFlag(vstring string) []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
minVersion, err := utilversion.ParseGeneric(MinWaitVersion)
|
||||
minVersion, err := utilversion.ParseGeneric(WaitMinVersion)
|
||||
if err != nil {
|
||||
glog.Errorf("MinWaitVersion (%s) is not a valid version string: %v", MinWaitVersion, err)
|
||||
glog.Errorf("WaitMinVersion (%s) is not a valid version string: %v", WaitMinVersion, err)
|
||||
return nil
|
||||
}
|
||||
if version.LessThan(minVersion) {
|
||||
return nil
|
||||
}
|
||||
|
||||
minVersion, err = utilversion.ParseGeneric(MinWait2Version)
|
||||
minVersion, err = utilversion.ParseGeneric(WaitSecondsMinVersion)
|
||||
if err != nil {
|
||||
glog.Errorf("MinWait2Version (%s) is not a valid version string: %v", MinWait2Version, err)
|
||||
glog.Errorf("WaitSecondsMinVersion (%s) is not a valid version string: %v", WaitSecondsMinVersion, err)
|
||||
return nil
|
||||
}
|
||||
if version.LessThan(minVersion) {
|
||||
return []string{"-w"}
|
||||
return []string{WaitString}
|
||||
} else {
|
||||
return []string{"-w2"}
|
||||
return []string{WaitSecondsString}
|
||||
}
|
||||
}
|
||||
|
||||
// getIPTablesVersionString runs "iptables --version" to get the version string
|
||||
// in the form "X.X.X"
|
||||
func getIPTablesVersionString(exec utilexec.Interface) (string, error) {
|
||||
func getIPTablesVersionString(exec utilexec.Interface, protocol Protocol) (string, error) {
|
||||
// this doesn't access mutable state so we don't need to use the interface / runner
|
||||
bytes, err := exec.Command(cmdIPTables, "--version").CombinedOutput()
|
||||
iptablesCmd := iptablesCommand(protocol)
|
||||
bytes, err := exec.Command(iptablesCmd, "--version").CombinedOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -558,8 +581,8 @@ func getIPTablesVersionString(exec utilexec.Interface) (string, error) {
|
|||
// --wait support landed in v1.6.1+ right before --version support, so
|
||||
// any version of iptables-restore that supports --version will also
|
||||
// support --wait
|
||||
func getIPTablesRestoreWaitFlag(exec utilexec.Interface) []string {
|
||||
vstring, err := getIPTablesRestoreVersionString(exec)
|
||||
func getIPTablesRestoreWaitFlag(exec utilexec.Interface, protocol Protocol) []string {
|
||||
vstring, err := getIPTablesRestoreVersionString(exec, protocol)
|
||||
if err != nil || vstring == "" {
|
||||
glog.V(3).Infof("couldn't get iptables-restore version; assuming it doesn't support --wait")
|
||||
return nil
|
||||
|
@ -574,13 +597,14 @@ func getIPTablesRestoreWaitFlag(exec utilexec.Interface) []string {
|
|||
|
||||
// getIPTablesRestoreVersionString runs "iptables-restore --version" to get the version string
|
||||
// in the form "X.X.X"
|
||||
func getIPTablesRestoreVersionString(exec utilexec.Interface) (string, error) {
|
||||
func getIPTablesRestoreVersionString(exec utilexec.Interface, protocol Protocol) (string, error) {
|
||||
// this doesn't access mutable state so we don't need to use the interface / runner
|
||||
|
||||
// iptables-restore hasn't always had --version, and worse complains
|
||||
// about unrecognized commands but doesn't exit when it gets them.
|
||||
// Work around that by setting stdin to nothing so it exits immediately.
|
||||
cmd := exec.Command(cmdIPTablesRestore, "--version")
|
||||
iptablesRestoreCmd := iptablesRestoreCommand(protocol)
|
||||
cmd := exec.Command(iptablesRestoreCmd, "--version")
|
||||
cmd.SetStdin(bytes.NewReader([]byte{}))
|
||||
bytes, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
|
|
24
vendor/k8s.io/kubernetes/pkg/util/mount/fake.go
generated
vendored
24
vendor/k8s.io/kubernetes/pkg/util/mount/fake.go
generated
vendored
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package mount
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
|
@ -125,7 +126,7 @@ func (f *FakeMounter) List() ([]MountPoint, error) {
|
|||
}
|
||||
|
||||
func (f *FakeMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
|
||||
return (mp.Path == dir)
|
||||
return mp.Path == dir
|
||||
}
|
||||
|
||||
func (f *FakeMounter) IsNotMountPoint(dir string) (bool, error) {
|
||||
|
@ -136,6 +137,11 @@ func (f *FakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
|||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
_, err := os.Stat(file)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
// If file is a symlink, get its absolute path
|
||||
absFile, err := filepath.EvalSymlinks(file)
|
||||
if err != nil {
|
||||
|
@ -175,3 +181,19 @@ func (f *FakeMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (strin
|
|||
func (f *FakeMounter) MakeRShared(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakeMounter) GetFileType(pathname string) (FileType, error) {
|
||||
return FileType("fake"), nil
|
||||
}
|
||||
|
||||
func (f *FakeMounter) MakeDir(pathname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakeMounter) MakeFile(pathname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakeMounter) ExistsPath(pathname string) bool {
|
||||
return false
|
||||
}
|
||||
|
|
91
vendor/k8s.io/kubernetes/pkg/util/mount/mount.go
generated
vendored
91
vendor/k8s.io/kubernetes/pkg/util/mount/mount.go
generated
vendored
|
@ -19,18 +19,20 @@ limitations under the License.
|
|||
package mount
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
type FileType string
|
||||
|
||||
const (
|
||||
// Default mount command if mounter path is not specified
|
||||
defaultMountCommand = "mount"
|
||||
MountsInGlobalPDPath = "mounts"
|
||||
defaultMountCommand = "mount"
|
||||
MountsInGlobalPDPath = "mounts"
|
||||
FileTypeDirectory FileType = "Directory"
|
||||
FileTypeFile FileType = "File"
|
||||
FileTypeSocket FileType = "Socket"
|
||||
FileTypeCharDev FileType = "CharDevice"
|
||||
FileTypeBlockDev FileType = "BlockDevice"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
|
@ -70,6 +72,18 @@ type Interface interface {
|
|||
// MakeRShared checks that given path is on a mount with 'rshared' mount
|
||||
// propagation. If not, it bind-mounts the path as rshared.
|
||||
MakeRShared(path string) error
|
||||
// GetFileType checks for file/directory/socket/block/character devices.
|
||||
// Will operate in the host mount namespace if kubelet is running in a container
|
||||
GetFileType(pathname string) (FileType, error)
|
||||
// MakeFile creates an empty file.
|
||||
// Will operate in the host mount namespace if kubelet is running in a container
|
||||
MakeFile(pathname string) error
|
||||
// MakeDir creates a new directory.
|
||||
// Will operate in the host mount namespace if kubelet is running in a container
|
||||
MakeDir(pathname string) error
|
||||
// ExistsPath checks whether the path exists.
|
||||
// Will operate in the host mount namespace if kubelet is running in a container
|
||||
ExistsPath(pathname string) bool
|
||||
}
|
||||
|
||||
// Exec executes command where mount utilities are. This can be either the host,
|
||||
|
@ -119,41 +133,6 @@ func (mounter *SafeFormatAndMount) FormatAndMount(source string, target string,
|
|||
return mounter.formatAndMount(source, target, fstype, options)
|
||||
}
|
||||
|
||||
// GetMountRefs finds all other references to the device referenced
|
||||
// by mountPath; returns a list of paths.
|
||||
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
|
||||
mps, err := mounter.List()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Find the device name.
|
||||
deviceName := ""
|
||||
// If mountPath is symlink, need get its target path.
|
||||
slTarget, err := filepath.EvalSymlinks(mountPath)
|
||||
if err != nil {
|
||||
slTarget = mountPath
|
||||
}
|
||||
for i := range mps {
|
||||
if mps[i].Path == slTarget {
|
||||
deviceName = mps[i].Device
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Find all references to the device.
|
||||
var refs []string
|
||||
if deviceName == "" {
|
||||
glog.Warningf("could not determine device for path: %q", mountPath)
|
||||
} else {
|
||||
for i := range mps {
|
||||
if mps[i].Device == deviceName && mps[i].Path != slTarget {
|
||||
refs = append(refs, mps[i].Path)
|
||||
}
|
||||
}
|
||||
}
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
// GetMountRefsByDev finds all references to the device provided
|
||||
// by mountPath; returns a list of paths.
|
||||
func GetMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
|
||||
|
@ -220,34 +199,6 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e
|
|||
return device, refCount, nil
|
||||
}
|
||||
|
||||
// getDeviceNameFromMount find the device name from /proc/mounts in which
|
||||
// the mount path reference should match the given plugin directory. In case no mount path reference
|
||||
// matches, returns the volume name taken from its given mountPath
|
||||
func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
|
||||
refs, err := GetMountRefs(mounter, mountPath)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err)
|
||||
return "", err
|
||||
}
|
||||
if len(refs) == 0 {
|
||||
glog.V(4).Infof("Directory %s is not mounted", mountPath)
|
||||
return "", fmt.Errorf("directory %s is not mounted", mountPath)
|
||||
}
|
||||
basemountPath := path.Join(pluginDir, MountsInGlobalPDPath)
|
||||
for _, ref := range refs {
|
||||
if strings.HasPrefix(ref, basemountPath) {
|
||||
volumeID, err := filepath.Rel(basemountPath, ref)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err)
|
||||
return "", err
|
||||
}
|
||||
return volumeID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return path.Base(mountPath), nil
|
||||
}
|
||||
|
||||
// IsNotMountPoint determines if a directory is a mountpoint.
|
||||
// It should return ErrNotExist when the directory does not exist.
|
||||
// This method uses the List() of all mountpoints
|
||||
|
|
170
vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux.go
generated
vendored
170
vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux.go
generated
vendored
|
@ -22,6 +22,8 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
@ -42,9 +44,6 @@ const (
|
|||
procMountsPath = "/proc/mounts"
|
||||
// Location of the mountinfo file
|
||||
procMountInfoPath = "/proc/self/mountinfo"
|
||||
)
|
||||
|
||||
const (
|
||||
// 'fsck' found errors and corrected them
|
||||
fsckErrorsCorrected = 1
|
||||
// 'fsck' found errors but exited without correcting them
|
||||
|
@ -71,12 +70,12 @@ func New(mounterPath string) Interface {
|
|||
|
||||
// Mount mounts source to target as fstype with given options. 'source' and 'fstype' must
|
||||
// be an emtpy string in case it's not required, e.g. for remount, or for auto filesystem
|
||||
// type, where kernel handles fs type for you. The mount 'options' is a list of options,
|
||||
// type, where kernel handles fstype for you. The mount 'options' is a list of options,
|
||||
// currently come from mount(8), e.g. "ro", "remount", "bind", etc. If no more option is
|
||||
// required, call Mount with an empty string list or nil.
|
||||
func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error {
|
||||
// Path to mounter binary if containerized mounter is needed. Otherwise, it is set to empty.
|
||||
// All Linux distros are expected to be shipped with a mount utility that an support bind mounts.
|
||||
// All Linux distros are expected to be shipped with a mount utility that a support bind mounts.
|
||||
mounterPath := ""
|
||||
bind, bindRemountOpts := isBind(options)
|
||||
if bind {
|
||||
|
@ -144,6 +143,41 @@ func (m *Mounter) doMount(mounterPath string, mountCmd string, source string, ta
|
|||
return err
|
||||
}
|
||||
|
||||
// GetMountRefs finds all other references to the device referenced
|
||||
// by mountPath; returns a list of paths.
|
||||
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
|
||||
mps, err := mounter.List()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Find the device name.
|
||||
deviceName := ""
|
||||
// If mountPath is symlink, need get its target path.
|
||||
slTarget, err := filepath.EvalSymlinks(mountPath)
|
||||
if err != nil {
|
||||
slTarget = mountPath
|
||||
}
|
||||
for i := range mps {
|
||||
if mps[i].Path == slTarget {
|
||||
deviceName = mps[i].Device
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Find all references to the device.
|
||||
var refs []string
|
||||
if deviceName == "" {
|
||||
glog.Warningf("could not determine device for path: %q", mountPath)
|
||||
} else {
|
||||
for i := range mps {
|
||||
if mps[i].Device == deviceName && mps[i].Path != slTarget {
|
||||
refs = append(refs, mps[i].Path)
|
||||
}
|
||||
}
|
||||
}
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
// detectSystemd returns true if OS runs with systemd as init. When not sure
|
||||
// (permission errors, ...), it returns false.
|
||||
// There may be different ways how to detect systemd, this one makes sure that
|
||||
|
@ -255,17 +289,29 @@ func (mounter *Mounter) DeviceOpened(pathname string) (bool, error) {
|
|||
// PathIsDevice uses FileInfo returned from os.Stat to check if path refers
|
||||
// to a device.
|
||||
func (mounter *Mounter) PathIsDevice(pathname string) (bool, error) {
|
||||
return pathIsDevice(pathname)
|
||||
pathType, err := mounter.GetFileType(pathname)
|
||||
isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev
|
||||
return isDevice, err
|
||||
}
|
||||
|
||||
func exclusiveOpenFailsOnDevice(pathname string) (bool, error) {
|
||||
isDevice, err := pathIsDevice(pathname)
|
||||
var isDevice bool
|
||||
finfo, err := os.Stat(pathname)
|
||||
if os.IsNotExist(err) {
|
||||
isDevice = false
|
||||
}
|
||||
// err in call to os.Stat
|
||||
if err != nil {
|
||||
return false, fmt.Errorf(
|
||||
"PathIsDevice failed for path %q: %v",
|
||||
pathname,
|
||||
err)
|
||||
}
|
||||
// path refers to a device
|
||||
if finfo.Mode()&os.ModeDevice != 0 {
|
||||
isDevice = true
|
||||
}
|
||||
|
||||
if !isDevice {
|
||||
glog.Errorf("Path %q is not refering to a device.", pathname)
|
||||
return false, nil
|
||||
|
@ -285,28 +331,39 @@ func exclusiveOpenFailsOnDevice(pathname string) (bool, error) {
|
|||
return false, errno
|
||||
}
|
||||
|
||||
func pathIsDevice(pathname string) (bool, error) {
|
||||
finfo, err := os.Stat(pathname)
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
// err in call to os.Stat
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// path refers to a device
|
||||
if finfo.Mode()&os.ModeDevice != 0 {
|
||||
return true, nil
|
||||
}
|
||||
// path does not refer to device
|
||||
return false, nil
|
||||
}
|
||||
|
||||
//GetDeviceNameFromMount: given a mount point, find the device name from its global mount point
|
||||
func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
|
||||
return getDeviceNameFromMount(mounter, mountPath, pluginDir)
|
||||
}
|
||||
|
||||
// getDeviceNameFromMount find the device name from /proc/mounts in which
|
||||
// the mount path reference should match the given plugin directory. In case no mount path reference
|
||||
// matches, returns the volume name taken from its given mountPath
|
||||
func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
|
||||
refs, err := GetMountRefs(mounter, mountPath)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err)
|
||||
return "", err
|
||||
}
|
||||
if len(refs) == 0 {
|
||||
glog.V(4).Infof("Directory %s is not mounted", mountPath)
|
||||
return "", fmt.Errorf("directory %s is not mounted", mountPath)
|
||||
}
|
||||
basemountPath := path.Join(pluginDir, MountsInGlobalPDPath)
|
||||
for _, ref := range refs {
|
||||
if strings.HasPrefix(ref, basemountPath) {
|
||||
volumeID, err := filepath.Rel(basemountPath, ref)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err)
|
||||
return "", err
|
||||
}
|
||||
return volumeID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return path.Base(mountPath), nil
|
||||
}
|
||||
|
||||
func listProcMounts(mountFilePath string) ([]MountPoint, error) {
|
||||
content, err := utilio.ConsistentRead(mountFilePath, maxListTries)
|
||||
if err != nil {
|
||||
|
@ -353,9 +410,64 @@ func parseProcMounts(content []byte) ([]MountPoint, error) {
|
|||
}
|
||||
|
||||
func (mounter *Mounter) MakeRShared(path string) error {
|
||||
mountCmd := defaultMountCommand
|
||||
mountArgs := []string{}
|
||||
return doMakeRShared(path, procMountInfoPath, mountCmd, mountArgs)
|
||||
return doMakeRShared(path, procMountInfoPath)
|
||||
}
|
||||
|
||||
func (mounter *Mounter) GetFileType(pathname string) (FileType, error) {
|
||||
var pathType FileType
|
||||
finfo, err := os.Stat(pathname)
|
||||
if os.IsNotExist(err) {
|
||||
return pathType, fmt.Errorf("path %q does not exist", pathname)
|
||||
}
|
||||
// err in call to os.Stat
|
||||
if err != nil {
|
||||
return pathType, err
|
||||
}
|
||||
|
||||
mode := finfo.Sys().(*syscall.Stat_t).Mode
|
||||
switch mode & syscall.S_IFMT {
|
||||
case syscall.S_IFSOCK:
|
||||
return FileTypeSocket, nil
|
||||
case syscall.S_IFBLK:
|
||||
return FileTypeBlockDev, nil
|
||||
case syscall.S_IFCHR:
|
||||
return FileTypeBlockDev, nil
|
||||
case syscall.S_IFDIR:
|
||||
return FileTypeDirectory, nil
|
||||
case syscall.S_IFREG:
|
||||
return FileTypeFile, nil
|
||||
}
|
||||
|
||||
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
|
||||
}
|
||||
|
||||
func (mounter *Mounter) MakeDir(pathname string) error {
|
||||
err := os.MkdirAll(pathname, os.FileMode(0755))
|
||||
if err != nil {
|
||||
if !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mounter *Mounter) MakeFile(pathname string) error {
|
||||
f, err := os.OpenFile(pathname, os.O_CREATE, os.FileMode(0644))
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
if !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mounter *Mounter) ExistsPath(pathname string) bool {
|
||||
_, err := os.Stat(pathname)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// formatAndMount uses unix utils to format and mount the given disk
|
||||
|
@ -424,7 +536,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
|||
return mountErr
|
||||
}
|
||||
|
||||
// diskLooksUnformatted uses 'lsblk' to see if the given disk is unformated
|
||||
// getDiskFormat uses 'lsblk' to see if the given disk is unformated
|
||||
func (mounter *SafeFormatAndMount) getDiskFormat(disk string) (string, error) {
|
||||
args := []string{"-n", "-o", "FSTYPE", disk}
|
||||
glog.V(4).Infof("Attempting to determine if disk %q is formatted using lsblk with args: (%v)", disk, args)
|
||||
|
@ -526,7 +638,7 @@ func parseMountInfo(filename string) ([]mountInfo, error) {
|
|||
// path is shared and bind-mounts it as rshared if needed. mountCmd and
|
||||
// mountArgs are expected to contain mount-like command, doMakeRShared will add
|
||||
// '--bind <path> <path>' and '--make-rshared <path>' to mountArgs.
|
||||
func doMakeRShared(path string, mountInfoFilename string, mountCmd string, mountArgs []string) error {
|
||||
func doMakeRShared(path string, mountInfoFilename string) error {
|
||||
shared, err := isShared(path, mountInfoFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
30
vendor/k8s.io/kubernetes/pkg/util/mount/mount_unsupported.go
generated
vendored
30
vendor/k8s.io/kubernetes/pkg/util/mount/mount_unsupported.go
generated
vendored
|
@ -18,6 +18,10 @@ limitations under the License.
|
|||
|
||||
package mount
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type Mounter struct {
|
||||
mounterPath string
|
||||
}
|
||||
|
@ -39,6 +43,12 @@ func (mounter *Mounter) Unmount(target string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetMountRefs finds all other references to the device referenced
|
||||
// by mountPath; returns a list of paths.
|
||||
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (mounter *Mounter) List() ([]MountPoint, error) {
|
||||
return []MountPoint{}, nil
|
||||
}
|
||||
|
@ -59,6 +69,10 @@ func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (str
|
|||
return "", nil
|
||||
}
|
||||
|
||||
func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (mounter *Mounter) DeviceOpened(pathname string) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
@ -78,3 +92,19 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
|||
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (mounter *Mounter) GetFileType(pathname string) (FileType, error) {
|
||||
return FileType("fake"), errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (mounter *Mounter) MakeDir(pathname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mounter *Mounter) MakeFile(pathname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mounter *Mounter) ExistsPath(pathname string) bool {
|
||||
return true
|
||||
}
|
||||
|
|
147
vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows.go
generated
vendored
147
vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows.go
generated
vendored
|
@ -22,9 +22,11 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@ -74,8 +76,24 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
|
|||
return nil
|
||||
}
|
||||
|
||||
// empty implementation for mounting azure file
|
||||
return os.MkdirAll(target, 0755)
|
||||
// currently only cifs mount is supported
|
||||
if strings.ToLower(fstype) != "cifs" {
|
||||
return fmt.Errorf("azureMount: only cifs mount is supported now, fstype: %q, mounting source (%q), target (%q), with options (%q)", fstype, source, target, options)
|
||||
}
|
||||
|
||||
cmdLine := fmt.Sprintf(`$User = "%s";$PWord = ConvertTo-SecureString -String "%s" -AsPlainText -Force;`+
|
||||
`$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord`,
|
||||
options[0], options[1])
|
||||
|
||||
bindSource = source
|
||||
cmdLine += fmt.Sprintf(";New-SmbGlobalMapping -RemotePath %s -Credential $Credential", source)
|
||||
|
||||
if output, err := exec.Command("powershell", "/c", cmdLine).CombinedOutput(); err != nil {
|
||||
// we don't return error here, even though New-SmbGlobalMapping failed, we still make it successful,
|
||||
// will return error when Windows 2016 RS3 is ready on azure
|
||||
glog.Errorf("azureMount: SmbGlobalMapping failed: %v, only SMB mount is supported now, output: %q", err, string(output))
|
||||
return os.MkdirAll(target, 0755)
|
||||
}
|
||||
}
|
||||
|
||||
if output, err := exec.Command("cmd", "/c", "mklink", "/D", target, bindSource).CombinedOutput(); err != nil {
|
||||
|
@ -97,6 +115,16 @@ func (mounter *Mounter) Unmount(target string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetMountRefs finds all other references to the device(drive) referenced
|
||||
// by mountPath; returns a list of paths.
|
||||
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
|
||||
refs, err := getAllParentLinks(normalizeWindowsPath(mountPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
// List returns a list of all mounted filesystems. todo
|
||||
func (mounter *Mounter) List() ([]MountPoint, error) {
|
||||
return []MountPoint{}, nil
|
||||
|
@ -131,6 +159,33 @@ func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (str
|
|||
return getDeviceNameFromMount(mounter, mountPath, pluginDir)
|
||||
}
|
||||
|
||||
// getDeviceNameFromMount find the device(drive) name in which
|
||||
// the mount path reference should match the given plugin directory. In case no mount path reference
|
||||
// matches, returns the volume name taken from its given mountPath
|
||||
func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
|
||||
refs, err := GetMountRefs(mounter, mountPath)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err)
|
||||
return "", err
|
||||
}
|
||||
if len(refs) == 0 {
|
||||
return "", fmt.Errorf("directory %s is not mounted", mountPath)
|
||||
}
|
||||
basemountPath := normalizeWindowsPath(path.Join(pluginDir, MountsInGlobalPDPath))
|
||||
for _, ref := range refs {
|
||||
if strings.Contains(ref, basemountPath) {
|
||||
volumeID, err := filepath.Rel(normalizeWindowsPath(basemountPath), ref)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err)
|
||||
return "", err
|
||||
}
|
||||
return volumeID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return path.Base(mountPath), nil
|
||||
}
|
||||
|
||||
// DeviceOpened determines if the device is in use elsewhere
|
||||
func (mounter *Mounter) DeviceOpened(pathname string) (bool, error) {
|
||||
return false, nil
|
||||
|
@ -147,6 +202,67 @@ func (mounter *Mounter) MakeRShared(path string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetFileType checks for sockets/block/character devices
|
||||
func (mounter *Mounter) GetFileType(pathname string) (FileType, error) {
|
||||
var pathType FileType
|
||||
info, err := os.Stat(pathname)
|
||||
if os.IsNotExist(err) {
|
||||
return pathType, fmt.Errorf("path %q does not exist", pathname)
|
||||
}
|
||||
// err in call to os.Stat
|
||||
if err != nil {
|
||||
return pathType, err
|
||||
}
|
||||
|
||||
mode := info.Sys().(*syscall.Win32FileAttributeData).FileAttributes
|
||||
switch mode & syscall.S_IFMT {
|
||||
case syscall.S_IFSOCK:
|
||||
return FileTypeSocket, nil
|
||||
case syscall.S_IFBLK:
|
||||
return FileTypeBlockDev, nil
|
||||
case syscall.S_IFCHR:
|
||||
return FileTypeCharDev, nil
|
||||
case syscall.S_IFDIR:
|
||||
return FileTypeDirectory, nil
|
||||
case syscall.S_IFREG:
|
||||
return FileTypeFile, nil
|
||||
}
|
||||
|
||||
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
|
||||
}
|
||||
|
||||
// MakeFile creates a new directory
|
||||
func (mounter *Mounter) MakeDir(pathname string) error {
|
||||
err := os.MkdirAll(pathname, os.FileMode(0755))
|
||||
if err != nil {
|
||||
if !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MakeFile creates an empty file
|
||||
func (mounter *Mounter) MakeFile(pathname string) error {
|
||||
f, err := os.OpenFile(pathname, os.O_CREATE, os.FileMode(0644))
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
if !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExistsPath checks whether the path exists
|
||||
func (mounter *Mounter) ExistsPath(pathname string) bool {
|
||||
_, err := os.Stat(pathname)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, fstype string, options []string) error {
|
||||
// Try to mount the disk
|
||||
glog.V(4).Infof("Attempting to formatAndMount disk: %s %s %s", fstype, source, target)
|
||||
|
@ -204,3 +320,30 @@ func getDriveLetterByDiskNumber(diskNum string, exec Exec) (string, error) {
|
|||
}
|
||||
return string(output)[:1], nil
|
||||
}
|
||||
|
||||
// getAllParentLinks walks all symbolic links and return all the parent targets recursively
|
||||
func getAllParentLinks(path string) ([]string, error) {
|
||||
const maxIter = 255
|
||||
links := []string{}
|
||||
for {
|
||||
links = append(links, path)
|
||||
if len(links) > maxIter {
|
||||
return links, fmt.Errorf("unexpected length of parent links: %v", links)
|
||||
}
|
||||
|
||||
fi, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return links, fmt.Errorf("Lstat: %v", err)
|
||||
}
|
||||
if fi.Mode()&os.ModeSymlink == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
path, err = os.Readlink(path)
|
||||
if err != nil {
|
||||
return links, fmt.Errorf("Readlink error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return links, nil
|
||||
}
|
||||
|
|
184
vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount.go
generated
vendored
184
vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount.go
generated
vendored
|
@ -25,78 +25,30 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/utils/exec"
|
||||
"k8s.io/kubernetes/pkg/util/nsenter"
|
||||
)
|
||||
|
||||
// NsenterMounter is part of experimental support for running the kubelet
|
||||
// in a container. Currently, all docker containers receive their own mount
|
||||
// namespaces. NsenterMounter works by executing nsenter to run commands in
|
||||
const (
|
||||
// hostProcMountsPath is the default mount path for rootfs
|
||||
hostProcMountsPath = "/rootfs/proc/1/mounts"
|
||||
// hostProcMountinfoPath is the default mount info path for rootfs
|
||||
hostProcMountinfoPath = "/rootfs/proc/1/mountinfo"
|
||||
)
|
||||
|
||||
// Currently, all docker containers receive their own mount namespaces.
|
||||
// NsenterMounter works by executing nsenter to run commands in
|
||||
// the host's mount namespace.
|
||||
//
|
||||
// NsenterMounter requires:
|
||||
//
|
||||
// 1. Docker >= 1.6 due to the dependency on the slave propagation mode
|
||||
// of the bind-mount of the kubelet root directory in the container.
|
||||
// Docker 1.5 used a private propagation mode for bind-mounts, so mounts
|
||||
// performed in the host's mount namespace do not propagate out to the
|
||||
// bind-mount in this docker version.
|
||||
// 2. The host's root filesystem must be available at /rootfs
|
||||
// 3. The nsenter binary must be on the Kubelet process' PATH in the container's
|
||||
// filesystem.
|
||||
// 4. The Kubelet process must have CAP_SYS_ADMIN (required by nsenter); at
|
||||
// the present, this effectively means that the kubelet is running in a
|
||||
// privileged container.
|
||||
// 5. The volume path used by the Kubelet must be the same inside and outside
|
||||
// the container and be writable by the container (to initialize volume)
|
||||
// contents. TODO: remove this requirement.
|
||||
// 6. The host image must have mount, findmnt, and umount binaries in /bin,
|
||||
// /usr/sbin, or /usr/bin
|
||||
// 7. The host image should have systemd-run in /bin, /usr/sbin, or /usr/bin
|
||||
// For more information about mount propagation modes, see:
|
||||
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
|
||||
type NsenterMounter struct {
|
||||
// a map of commands to their paths on the host filesystem
|
||||
paths map[string]string
|
||||
ne *nsenter.Nsenter
|
||||
}
|
||||
|
||||
func NewNsenterMounter() *NsenterMounter {
|
||||
m := &NsenterMounter{
|
||||
paths: map[string]string{
|
||||
"mount": "",
|
||||
"findmnt": "",
|
||||
"umount": "",
|
||||
"systemd-run": "",
|
||||
},
|
||||
}
|
||||
// search for the mount command in other locations besides /usr/bin
|
||||
for binary := range m.paths {
|
||||
// default to root
|
||||
m.paths[binary] = filepath.Join("/", binary)
|
||||
for _, path := range []string{"/bin", "/usr/sbin", "/usr/bin"} {
|
||||
binPath := filepath.Join(path, binary)
|
||||
if _, err := os.Stat(filepath.Join(hostRootFsPath, binPath)); err != nil {
|
||||
continue
|
||||
}
|
||||
m.paths[binary] = binPath
|
||||
break
|
||||
}
|
||||
// TODO: error, so that the kubelet can stop if the mounts don't exist
|
||||
// (don't forget that systemd-run is optional)
|
||||
}
|
||||
return m
|
||||
return &NsenterMounter{ne: nsenter.NewNsenter()}
|
||||
}
|
||||
|
||||
// NsenterMounter implements mount.Interface
|
||||
var _ = Interface(&NsenterMounter{})
|
||||
|
||||
const (
|
||||
hostRootFsPath = "/rootfs"
|
||||
hostProcMountsPath = "/rootfs/proc/1/mounts"
|
||||
hostProcMountinfoPath = "/rootfs/proc/1/mountinfo"
|
||||
hostMountNamespacePath = "/rootfs/proc/1/ns/mnt"
|
||||
nsenterPath = "nsenter"
|
||||
)
|
||||
|
||||
// Mount runs mount(8) in the host's root mount namespace. Aside from this
|
||||
// aspect, Mount has the same semantics as the mounter returned by mount.New()
|
||||
func (n *NsenterMounter) Mount(source string, target string, fstype string, options []string) error {
|
||||
|
@ -116,26 +68,22 @@ func (n *NsenterMounter) Mount(source string, target string, fstype string, opti
|
|||
// doNsenterMount nsenters the host's mount namespace and performs the
|
||||
// requested mount.
|
||||
func (n *NsenterMounter) doNsenterMount(source, target, fstype string, options []string) error {
|
||||
glog.V(5).Infof("nsenter Mounting %s %s %s %v", source, target, fstype, options)
|
||||
args := n.makeNsenterArgs(source, target, fstype, options)
|
||||
|
||||
glog.V(5).Infof("Mount command: %v %v", nsenterPath, args)
|
||||
exec := exec.New()
|
||||
outputBytes, err := exec.Command(nsenterPath, args...).CombinedOutput()
|
||||
glog.V(5).Infof("nsenter mount %s %s %s %v", source, target, fstype, options)
|
||||
cmd, args := n.makeNsenterArgs(source, target, fstype, options)
|
||||
outputBytes, err := n.ne.Exec(cmd, args).CombinedOutput()
|
||||
if len(outputBytes) != 0 {
|
||||
glog.V(5).Infof("Output of mounting %s to %s: %v", source, target, string(outputBytes))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// makeNsenterArgs makes a list of argument to nsenter in order to do the
|
||||
// requested mount.
|
||||
func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options []string) []string {
|
||||
mountCmd := n.absHostPath("mount")
|
||||
func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options []string) (string, []string) {
|
||||
mountCmd := n.ne.AbsHostPath("mount")
|
||||
mountArgs := makeMountArgs(source, target, fstype, options)
|
||||
|
||||
if systemdRunPath, hasSystemd := n.paths["systemd-run"]; hasSystemd {
|
||||
if systemdRunPath, hasSystemd := n.ne.SupportsSystemd(); hasSystemd {
|
||||
// Complete command line:
|
||||
// nsenter --mount=/rootfs/proc/1/ns/mnt -- /bin/systemd-run --description=... --scope -- /bin/mount -t <type> <what> <where>
|
||||
// Expected flow is:
|
||||
|
@ -165,34 +113,20 @@ func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options
|
|||
// No code here, mountCmd and mountArgs use /bin/mount
|
||||
}
|
||||
|
||||
nsenterArgs := []string{
|
||||
"--mount=" + hostMountNamespacePath,
|
||||
"--",
|
||||
mountCmd,
|
||||
}
|
||||
nsenterArgs = append(nsenterArgs, mountArgs...)
|
||||
|
||||
return nsenterArgs
|
||||
return mountCmd, mountArgs
|
||||
}
|
||||
|
||||
// Unmount runs umount(8) in the host's mount namespace.
|
||||
func (n *NsenterMounter) Unmount(target string) error {
|
||||
args := []string{
|
||||
"--mount=" + hostMountNamespacePath,
|
||||
"--",
|
||||
n.absHostPath("umount"),
|
||||
target,
|
||||
}
|
||||
args := []string{target}
|
||||
// No need to execute systemd-run here, it's enough that unmount is executed
|
||||
// in the host's mount namespace. It will finish appropriate fuse daemon(s)
|
||||
// running in any scope.
|
||||
glog.V(5).Infof("Unmount command: %v %v", nsenterPath, args)
|
||||
exec := exec.New()
|
||||
outputBytes, err := exec.Command(nsenterPath, args...).CombinedOutput()
|
||||
glog.V(5).Infof("nsenter unmount args: %v", args)
|
||||
outputBytes, err := n.ne.Exec("umount", args).CombinedOutput()
|
||||
if len(outputBytes) != 0 {
|
||||
glog.V(5).Infof("Output of unmounting %s: %v", target, string(outputBytes))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -207,7 +141,7 @@ func (m *NsenterMounter) IsNotMountPoint(dir string) (bool, error) {
|
|||
|
||||
func (*NsenterMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
|
||||
deletedDir := fmt.Sprintf("%s\\040(deleted)", dir)
|
||||
return ((mp.Path == dir) || (mp.Path == deletedDir))
|
||||
return (mp.Path == dir) || (mp.Path == deletedDir)
|
||||
}
|
||||
|
||||
// IsLikelyNotMountPoint determines whether a path is a mountpoint by calling findmnt
|
||||
|
@ -227,11 +161,9 @@ func (n *NsenterMounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
|||
// the first of multiple possible mountpoints using --first-only.
|
||||
// Also add fstype output to make sure that the output of target file will give the full path
|
||||
// TODO: Need more refactoring for this function. Track the solution with issue #26996
|
||||
args := []string{"--mount=" + hostMountNamespacePath, "--", n.absHostPath("findmnt"), "-o", "target,fstype", "--noheadings", "--first-only", "--target", file}
|
||||
glog.V(5).Infof("findmnt command: %v %v", nsenterPath, args)
|
||||
|
||||
exec := exec.New()
|
||||
out, err := exec.Command(nsenterPath, args...).CombinedOutput()
|
||||
args := []string{"-o", "target,fstype", "--noheadings", "--first-only", "--target", file}
|
||||
glog.V(5).Infof("nsenter findmnt args: %v", args)
|
||||
out, err := n.ne.Exec("findmnt", args).CombinedOutput()
|
||||
if err != nil {
|
||||
glog.V(2).Infof("Failed findmnt command for path %s: %v", file, err)
|
||||
// Different operating systems behave differently for paths which are not mount points.
|
||||
|
@ -277,7 +209,9 @@ func (n *NsenterMounter) DeviceOpened(pathname string) (bool, error) {
|
|||
// PathIsDevice uses FileInfo returned from os.Stat to check if path refers
|
||||
// to a device.
|
||||
func (n *NsenterMounter) PathIsDevice(pathname string) (bool, error) {
|
||||
return pathIsDevice(pathname)
|
||||
pathType, err := n.GetFileType(pathname)
|
||||
isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev
|
||||
return isDevice, err
|
||||
}
|
||||
|
||||
//GetDeviceNameFromMount given a mount point, find the volume id from checking /proc/mounts
|
||||
|
@ -285,20 +219,54 @@ func (n *NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (st
|
|||
return getDeviceNameFromMount(n, mountPath, pluginDir)
|
||||
}
|
||||
|
||||
func (n *NsenterMounter) absHostPath(command string) string {
|
||||
path, ok := n.paths[command]
|
||||
if !ok {
|
||||
return command
|
||||
}
|
||||
return path
|
||||
func (n *NsenterMounter) MakeRShared(path string) error {
|
||||
return doMakeRShared(path, hostProcMountinfoPath)
|
||||
}
|
||||
|
||||
func (n *NsenterMounter) MakeRShared(path string) error {
|
||||
nsenterCmd := nsenterPath
|
||||
nsenterArgs := []string{
|
||||
"--mount=" + hostMountNamespacePath,
|
||||
"--",
|
||||
n.absHostPath("mount"),
|
||||
func (mounter *NsenterMounter) GetFileType(pathname string) (FileType, error) {
|
||||
var pathType FileType
|
||||
outputBytes, err := mounter.ne.Exec("stat", []string{"-L", `--printf "%F"`, pathname}).CombinedOutput()
|
||||
if err != nil {
|
||||
return pathType, err
|
||||
}
|
||||
return doMakeRShared(path, hostProcMountinfoPath, nsenterCmd, nsenterArgs)
|
||||
|
||||
switch string(outputBytes) {
|
||||
case "socket":
|
||||
return FileTypeSocket, nil
|
||||
case "character special file":
|
||||
return FileTypeCharDev, nil
|
||||
case "block special file":
|
||||
return FileTypeBlockDev, nil
|
||||
case "directory":
|
||||
return FileTypeDirectory, nil
|
||||
case "regular file":
|
||||
return FileTypeFile, nil
|
||||
}
|
||||
|
||||
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
|
||||
}
|
||||
|
||||
func (mounter *NsenterMounter) MakeDir(pathname string) error {
|
||||
args := []string{"-p", pathname}
|
||||
if _, err := mounter.ne.Exec("mkdir", args).CombinedOutput(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mounter *NsenterMounter) MakeFile(pathname string) error {
|
||||
args := []string{pathname}
|
||||
if _, err := mounter.ne.Exec("touch", args).CombinedOutput(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mounter *NsenterMounter) ExistsPath(pathname string) bool {
|
||||
args := []string{pathname}
|
||||
_, err := mounter.ne.Exec("ls", args).CombinedOutput()
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
20
vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_unsupported.go
generated
vendored
20
vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_unsupported.go
generated
vendored
|
@ -18,6 +18,10 @@ limitations under the License.
|
|||
|
||||
package mount
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type NsenterMounter struct{}
|
||||
|
||||
func NewNsenterMounter() *NsenterMounter {
|
||||
|
@ -65,3 +69,19 @@ func (*NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (stri
|
|||
func (*NsenterMounter) MakeRShared(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*NsenterMounter) GetFileType(_ string) (FileType, error) {
|
||||
return FileType("fake"), errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (*NsenterMounter) MakeDir(pathname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*NsenterMounter) MakeFile(pathname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*NsenterMounter) ExistsPath(pathname string) bool {
|
||||
return true
|
||||
}
|
||||
|
|
124
vendor/k8s.io/kubernetes/pkg/util/nsenter/nsenter.go
generated
vendored
Normal file
124
vendor/k8s.io/kubernetes/pkg/util/nsenter/nsenter.go
generated
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2017 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 nsenter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"k8s.io/utils/exec"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
hostRootFsPath = "/rootfs"
|
||||
// hostProcMountNsPath is the default mount namespace for rootfs
|
||||
hostProcMountNsPath = "/rootfs/proc/1/ns/mnt"
|
||||
// nsenterPath is the default nsenter command
|
||||
nsenterPath = "nsenter"
|
||||
)
|
||||
|
||||
// Nsenter is part of experimental support for running the kubelet
|
||||
// in a container.
|
||||
//
|
||||
// Nsenter requires:
|
||||
//
|
||||
// 1. Docker >= 1.6 due to the dependency on the slave propagation mode
|
||||
// of the bind-mount of the kubelet root directory in the container.
|
||||
// Docker 1.5 used a private propagation mode for bind-mounts, so mounts
|
||||
// performed in the host's mount namespace do not propagate out to the
|
||||
// bind-mount in this docker version.
|
||||
// 2. The host's root filesystem must be available at /rootfs
|
||||
// 3. The nsenter binary must be on the Kubelet process' PATH in the container's
|
||||
// filesystem.
|
||||
// 4. The Kubelet process must have CAP_SYS_ADMIN (required by nsenter); at
|
||||
// the present, this effectively means that the kubelet is running in a
|
||||
// privileged container.
|
||||
// 5. The volume path used by the Kubelet must be the same inside and outside
|
||||
// the container and be writable by the container (to initialize volume)
|
||||
// contents. TODO: remove this requirement.
|
||||
// 6. The host image must have "mount", "findmnt", "umount", "stat", "touch",
|
||||
// "mkdir", "ls", "sh" and "chmod" binaries in /bin, /usr/sbin, or /usr/bin
|
||||
// 7. The host image should have systemd-run in /bin, /usr/sbin, or /usr/bin
|
||||
// For more information about mount propagation modes, see:
|
||||
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
|
||||
type Nsenter struct {
|
||||
// a map of commands to their paths on the host filesystem
|
||||
paths map[string]string
|
||||
}
|
||||
|
||||
// NewNsenter constructs a new instance of Nsenter
|
||||
func NewNsenter() *Nsenter {
|
||||
ne := &Nsenter{
|
||||
paths: map[string]string{
|
||||
"mount": "",
|
||||
"findmnt": "",
|
||||
"umount": "",
|
||||
"systemd-run": "",
|
||||
"stat": "",
|
||||
"touch": "",
|
||||
"mkdir": "",
|
||||
"ls": "",
|
||||
"sh": "",
|
||||
"chmod": "",
|
||||
},
|
||||
}
|
||||
// search for the required commands in other locations besides /usr/bin
|
||||
for binary := range ne.paths {
|
||||
// default to root
|
||||
ne.paths[binary] = filepath.Join("/", binary)
|
||||
for _, path := range []string{"/bin", "/usr/sbin", "/usr/bin"} {
|
||||
binPath := filepath.Join(path, binary)
|
||||
if _, err := os.Stat(filepath.Join(hostRootFsPath, binPath)); err != nil {
|
||||
continue
|
||||
}
|
||||
ne.paths[binary] = binPath
|
||||
break
|
||||
}
|
||||
// TODO: error, so that the kubelet can stop if the paths don't exist
|
||||
// (don't forget that systemd-run is optional)
|
||||
}
|
||||
return ne
|
||||
}
|
||||
|
||||
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
|
||||
func (ne *Nsenter) Exec(cmd string, args []string) exec.Cmd {
|
||||
fullArgs := append([]string{fmt.Sprintf("--mount=%s", hostProcMountNsPath), "--"},
|
||||
append([]string{ne.AbsHostPath(cmd)}, args...)...)
|
||||
glog.V(5).Infof("Running nsenter command: %v %v", nsenterPath, fullArgs)
|
||||
exec := exec.New()
|
||||
return exec.Command(nsenterPath, fullArgs...)
|
||||
}
|
||||
|
||||
// AbsHostPath returns the absolute runnable path for a specified command
|
||||
func (ne *Nsenter) AbsHostPath(command string) string {
|
||||
path, ok := ne.paths[command]
|
||||
if !ok {
|
||||
return command
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// SupportsSystemd checks whether command systemd-run exists
|
||||
func (ne *Nsenter) SupportsSystemd() (string, bool) {
|
||||
systemdRunPath, hasSystemd := ne.paths["systemd-run"]
|
||||
return systemdRunPath, hasSystemd
|
||||
}
|
50
vendor/k8s.io/kubernetes/pkg/util/nsenter/nsenter_unsupported.go
generated
vendored
Normal file
50
vendor/k8s.io/kubernetes/pkg/util/nsenter/nsenter_unsupported.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// +build !linux
|
||||
|
||||
/*
|
||||
Copyright 2017 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 nsenter
|
||||
|
||||
import (
|
||||
"k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
// Nsenter is part of experimental support for running the kubelet
|
||||
// in a container.
|
||||
type Nsenter struct {
|
||||
// a map of commands to their paths on the host filesystem
|
||||
Paths map[string]string
|
||||
}
|
||||
|
||||
// NewNsenter constructs a new instance of Nsenter
|
||||
func NewNsenter() *Nsenter {
|
||||
return &Nsenter{}
|
||||
}
|
||||
|
||||
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
|
||||
func (ne *Nsenter) Exec(args ...string) exec.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AbsHostPath returns the absolute runnable path for a specified command
|
||||
func (ne *Nsenter) AbsHostPath(command string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// SupportsSystemd checks whether command systemd-run exists
|
||||
func (ne *Nsenter) SupportsSystemd() (string, bool) {
|
||||
return "", false
|
||||
}
|
43
vendor/k8s.io/kubernetes/pkg/util/taints/taints.go
generated
vendored
43
vendor/k8s.io/kubernetes/pkg/util/taints/taints.go
generated
vendored
|
@ -35,7 +35,7 @@ const (
|
|||
UNTAINTED = "untainted"
|
||||
)
|
||||
|
||||
// parseTaint parses a taint from a string. Taint must be off the format '<key>=<value>:<effect>'.
|
||||
// parseTaint parses a taint from a string. Taint must be of the format '<key>=<value>:<effect>'.
|
||||
func parseTaint(st string) (v1.Taint, error) {
|
||||
var taint v1.Taint
|
||||
parts := strings.Split(st, "=")
|
||||
|
@ -45,15 +45,14 @@ func parseTaint(st string) (v1.Taint, error) {
|
|||
|
||||
parts2 := strings.Split(parts[1], ":")
|
||||
|
||||
effect := v1.TaintEffect(parts2[1])
|
||||
|
||||
errs := validation.IsValidLabelValue(parts2[0])
|
||||
if len(parts2) != 2 || len(errs) != 0 {
|
||||
return taint, fmt.Errorf("invalid taint spec: %v, %s", st, strings.Join(errs, "; "))
|
||||
}
|
||||
|
||||
if effect != v1.TaintEffectNoSchedule && effect != v1.TaintEffectPreferNoSchedule && effect != v1.TaintEffectNoExecute {
|
||||
return taint, fmt.Errorf("invalid taint spec: %v, unsupported taint effect", st)
|
||||
effect := v1.TaintEffect(parts2[1])
|
||||
if err := validateTaintEffect(effect); err != nil {
|
||||
return taint, err
|
||||
}
|
||||
|
||||
taint.Key = parts[0]
|
||||
|
@ -63,6 +62,14 @@ func parseTaint(st string) (v1.Taint, error) {
|
|||
return taint, nil
|
||||
}
|
||||
|
||||
func validateTaintEffect(effect v1.TaintEffect) error {
|
||||
if effect != v1.TaintEffectNoSchedule && effect != v1.TaintEffectPreferNoSchedule && effect != v1.TaintEffectNoExecute {
|
||||
return fmt.Errorf("invalid taint effect: %v, unsupported taint effect", effect)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewTaintsVar wraps []api.Taint in a struct that implements flag.Value to allow taints to be
|
||||
// bound to command line flags.
|
||||
func NewTaintsVar(ptr *[]api.Taint) taintsVar {
|
||||
|
@ -76,6 +83,10 @@ type taintsVar struct {
|
|||
}
|
||||
|
||||
func (t taintsVar) Set(s string) error {
|
||||
if len(s) == 0 {
|
||||
*t.ptr = nil
|
||||
return nil
|
||||
}
|
||||
sts := strings.Split(s, ",")
|
||||
var taints []api.Taint
|
||||
for _, st := range sts {
|
||||
|
@ -91,7 +102,7 @@ func (t taintsVar) Set(s string) error {
|
|||
|
||||
func (t taintsVar) String() string {
|
||||
if len(*t.ptr) == 0 {
|
||||
return "<nil>"
|
||||
return ""
|
||||
}
|
||||
var taints []string
|
||||
for _, taint := range *t.ptr {
|
||||
|
@ -134,6 +145,14 @@ func ParseTaints(spec []string) ([]v1.Taint, []v1.Taint, error) {
|
|||
taintKey = parts[0]
|
||||
effect = v1.TaintEffect(parts[1])
|
||||
}
|
||||
|
||||
// If effect is specified, need to validate it.
|
||||
if len(effect) > 0 {
|
||||
err := validateTaintEffect(effect)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
taintsToRemove = append(taintsToRemove, v1.Taint{Key: taintKey, Effect: effect})
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("unknown taint spec: %v", taintSpec)
|
||||
|
@ -238,11 +257,7 @@ func DeleteTaint(taints []v1.Taint, taintToDelete *v1.Taint) ([]v1.Taint, bool)
|
|||
// RemoveTaint tries to remove a taint from annotations list. Returns a new copy of updated Node and true if something was updated
|
||||
// false otherwise.
|
||||
func RemoveTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
|
||||
objCopy, err := api.Scheme.DeepCopy(node)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
newNode := objCopy.(*v1.Node)
|
||||
newNode := node.DeepCopy()
|
||||
nodeTaints := newNode.Spec.Taints
|
||||
if len(nodeTaints) == 0 {
|
||||
return newNode, false, nil
|
||||
|
@ -260,11 +275,7 @@ func RemoveTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
|
|||
// AddOrUpdateTaint tries to add a taint to annotations list. Returns a new copy of updated Node and true if something was updated
|
||||
// false otherwise.
|
||||
func AddOrUpdateTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
|
||||
objCopy, err := api.Scheme.DeepCopy(node)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
newNode := objCopy.(*v1.Node)
|
||||
newNode := node.DeepCopy()
|
||||
nodeTaints := newNode.Spec.Taints
|
||||
|
||||
var newTaints []v1.Taint
|
||||
|
|
39
vendor/k8s.io/kubernetes/pkg/util/version/version.go
generated
vendored
39
vendor/k8s.io/kubernetes/pkg/util/version/version.go
generated
vendored
|
@ -181,12 +181,11 @@ func (v *Version) String() string {
|
|||
// compareInternal returns -1 if v is less than other, 1 if it is greater than other, or 0
|
||||
// if they are equal
|
||||
func (v *Version) compareInternal(other *Version) int {
|
||||
for i := range v.components {
|
||||
|
||||
vLen := len(v.components)
|
||||
oLen := len(other.components)
|
||||
for i := 0; i < vLen && i < oLen; i++ {
|
||||
switch {
|
||||
case i >= len(other.components):
|
||||
if v.components[i] != 0 {
|
||||
return 1
|
||||
}
|
||||
case other.components[i] < v.components[i]:
|
||||
return 1
|
||||
case other.components[i] > v.components[i]:
|
||||
|
@ -194,6 +193,14 @@ func (v *Version) compareInternal(other *Version) int {
|
|||
}
|
||||
}
|
||||
|
||||
// If components are common but one has more items and they are not zeros, it is bigger
|
||||
switch {
|
||||
case oLen < vLen && !onlyZeros(v.components[oLen:]):
|
||||
return 1
|
||||
case oLen > vLen && !onlyZeros(other.components[vLen:]):
|
||||
return -1
|
||||
}
|
||||
|
||||
if !v.semver || !other.semver {
|
||||
return 0
|
||||
}
|
||||
|
@ -209,10 +216,7 @@ func (v *Version) compareInternal(other *Version) int {
|
|||
|
||||
vPR := strings.Split(v.preRelease, ".")
|
||||
oPR := strings.Split(other.preRelease, ".")
|
||||
for i := range vPR {
|
||||
if i >= len(oPR) {
|
||||
return 1
|
||||
}
|
||||
for i := 0; i < len(vPR) && i < len(oPR); i++ {
|
||||
vNum, err := strconv.ParseUint(vPR[i], 10, 0)
|
||||
if err == nil {
|
||||
oNum, err := strconv.ParseUint(oPR[i], 10, 0)
|
||||
|
@ -234,9 +238,26 @@ func (v *Version) compareInternal(other *Version) int {
|
|||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case len(oPR) < len(vPR):
|
||||
return 1
|
||||
case len(oPR) > len(vPR):
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// returns false if array contain any non-zero element
|
||||
func onlyZeros(array []uint) bool {
|
||||
for _, num := range array {
|
||||
if num != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// AtLeast tests if a version is at least equal to a given minimum version. If both
|
||||
// Versions are Semantic Versions, this will use the Semantic Version comparison
|
||||
// algorithm. Otherwise, it will compare only the numeric components, with non-present
|
||||
|
|
4
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
|
@ -69,8 +69,6 @@ type VolumeOptions struct {
|
|||
CloudTags *map[string]string
|
||||
// Volume provisioning parameters from StorageClass
|
||||
Parameters map[string]string
|
||||
// This flag helps identify whether kubelet is running in a container
|
||||
Containerized bool
|
||||
}
|
||||
|
||||
type DynamicPluginProber interface {
|
||||
|
@ -713,7 +711,7 @@ func NewPersistentVolumeRecyclerPodTemplate() *v1.Pod {
|
|||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "pv-recycler",
|
||||
Image: "gcr.io/google_containers/busybox",
|
||||
Image: "busybox:1.27",
|
||||
Command: []string{"/bin/sh"},
|
||||
Args: []string{"-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
|
|
64
vendor/k8s.io/kubernetes/pkg/volume/util.go
generated
vendored
64
vendor/k8s.io/kubernetes/pkg/volume/util.go
generated
vendored
|
@ -36,7 +36,6 @@ import (
|
|||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
volutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
type RecycleEventRecorder func(eventtype, message string)
|
||||
|
@ -48,8 +47,8 @@ type RecycleEventRecorder func(eventtype, message string)
|
|||
// attempted before returning.
|
||||
//
|
||||
// In case there is a pod with the same namespace+name already running, this
|
||||
// function assumes it's an older instance of the recycler pod and watches
|
||||
// this old pod instead of starting a new one.
|
||||
// function deletes it as it is not able to judge if it is an old recycler
|
||||
// or user has forged a fake recycler to block Kubernetes from recycling.//
|
||||
//
|
||||
// pod - the pod designed by a volume plugin to recycle the volume. pod.Name
|
||||
// will be overwritten with unique name based on PV.Name.
|
||||
|
@ -81,20 +80,44 @@ func internalRecycleVolumeByWatchingPodUntilCompletion(pvName string, pod *v1.Po
|
|||
_, err = recyclerClient.CreatePod(pod)
|
||||
if err != nil {
|
||||
if errors.IsAlreadyExists(err) {
|
||||
glog.V(5).Infof("old recycler pod %q found for volume", pod.Name)
|
||||
deleteErr := recyclerClient.DeletePod(pod.Name, pod.Namespace)
|
||||
if deleteErr != nil {
|
||||
return fmt.Errorf("failed to delete old recycler pod %s/%s: %s", pod.Namespace, pod.Name, deleteErr)
|
||||
}
|
||||
// Recycler will try again and the old pod will be hopefuly deleted
|
||||
// at that time.
|
||||
return fmt.Errorf("old recycler pod found, will retry later")
|
||||
} else {
|
||||
return fmt.Errorf("unexpected error creating recycler pod: %+v\n", err)
|
||||
}
|
||||
}
|
||||
defer func(pod *v1.Pod) {
|
||||
glog.V(2).Infof("deleting recycler pod %s/%s", pod.Namespace, pod.Name)
|
||||
if err := recyclerClient.DeletePod(pod.Name, pod.Namespace); err != nil {
|
||||
glog.Errorf("failed to delete recycler pod %s/%s: %v", pod.Namespace, pod.Name, err)
|
||||
}
|
||||
}(pod)
|
||||
err = waitForPod(pod, recyclerClient, podCh)
|
||||
|
||||
// Now only the old pod or the new pod run. Watch it until it finishes
|
||||
// and send all events on the pod to the PV
|
||||
// In all cases delete the recycler pod and log its result.
|
||||
glog.V(2).Infof("deleting recycler pod %s/%s", pod.Namespace, pod.Name)
|
||||
deleteErr := recyclerClient.DeletePod(pod.Name, pod.Namespace)
|
||||
if deleteErr != nil {
|
||||
glog.Errorf("failed to delete recycler pod %s/%s: %v", pod.Namespace, pod.Name, err)
|
||||
}
|
||||
|
||||
// Returning recycler error is preferred, the pod will be deleted again on
|
||||
// the next retry.
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to recycle volume: %s", err)
|
||||
}
|
||||
|
||||
// Recycle succeeded but we failed to delete the recycler pod. Report it,
|
||||
// the controller will re-try recycling the PV again shortly.
|
||||
if deleteErr != nil {
|
||||
return fmt.Errorf("failed to delete recycler pod: %s", deleteErr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// waitForPod watches the pod it until it finishes and send all events on the
|
||||
// pod to the PV.
|
||||
func waitForPod(pod *v1.Pod, recyclerClient recyclerClient, podCh <-chan watch.Event) error {
|
||||
for {
|
||||
event, ok := <-podCh
|
||||
if !ok {
|
||||
|
@ -164,15 +187,15 @@ type realRecyclerClient struct {
|
|||
}
|
||||
|
||||
func (c *realRecyclerClient) CreatePod(pod *v1.Pod) (*v1.Pod, error) {
|
||||
return c.client.Core().Pods(pod.Namespace).Create(pod)
|
||||
return c.client.CoreV1().Pods(pod.Namespace).Create(pod)
|
||||
}
|
||||
|
||||
func (c *realRecyclerClient) GetPod(name, namespace string) (*v1.Pod, error) {
|
||||
return c.client.Core().Pods(namespace).Get(name, metav1.GetOptions{})
|
||||
return c.client.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (c *realRecyclerClient) DeletePod(name, namespace string) error {
|
||||
return c.client.Core().Pods(namespace).Delete(name, nil)
|
||||
return c.client.CoreV1().Pods(namespace).Delete(name, nil)
|
||||
}
|
||||
|
||||
func (c *realRecyclerClient) Event(eventtype, message string) {
|
||||
|
@ -189,13 +212,13 @@ func (c *realRecyclerClient) WatchPod(name, namespace string, stopChannel chan s
|
|||
Watch: true,
|
||||
}
|
||||
|
||||
podWatch, err := c.client.Core().Pods(namespace).Watch(options)
|
||||
podWatch, err := c.client.CoreV1().Pods(namespace).Watch(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eventSelector, _ := fields.ParseSelector("involvedObject.name=" + name)
|
||||
eventWatch, err := c.client.Core().Events(namespace).Watch(metav1.ListOptions{
|
||||
eventWatch, err := c.client.CoreV1().Events(namespace).Watch(metav1.ListOptions{
|
||||
FieldSelector: eventSelector.String(),
|
||||
Watch: true,
|
||||
})
|
||||
|
@ -400,13 +423,6 @@ func getPVCNameHashAndIndexOffset(pvcName string) (hash uint32, index uint32) {
|
|||
func UnmountViaEmptyDir(dir string, host VolumeHost, volName string, volSpec Spec, podUID types.UID) error {
|
||||
glog.V(3).Infof("Tearing down volume %v for pod %v at %v", volName, podUID, dir)
|
||||
|
||||
if pathExists, pathErr := volutil.PathExists(dir); pathErr != nil {
|
||||
return fmt.Errorf("Error checking if path exists: %v", pathErr)
|
||||
} else if !pathExists {
|
||||
glog.Warningf("Warning: Unmount skipped because path does not exist: %v", dir)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Wrap EmptyDir, let it do the teardown.
|
||||
wrapped, err := host.NewWrapperUnmounter(volName, volSpec, podUID)
|
||||
if err != nil {
|
||||
|
|
5
vendor/k8s.io/kubernetes/pkg/volume/util/metrics.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/volume/util/metrics.go
generated
vendored
|
@ -24,8 +24,9 @@ import (
|
|||
|
||||
var storageOperationMetric = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "storage_operation_duration_seconds",
|
||||
Help: "Storage operation duration",
|
||||
Name: "storage_operation_duration_seconds",
|
||||
Help: "Storage operation duration",
|
||||
Buckets: []float64{.1, .25, .5, 1, 2.5, 5, 10, 15, 25, 50},
|
||||
},
|
||||
[]string{"volume_plugin", "operation_name"},
|
||||
)
|
||||
|
|
8
vendor/k8s.io/kubernetes/pkg/volume/util/util.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/volume/util/util.go
generated
vendored
|
@ -32,7 +32,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
v1helper "k8s.io/kubernetes/pkg/api/v1/helper"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
|
@ -147,7 +147,7 @@ func GetSecretForPod(pod *v1.Pod, secretName string, kubeClient clientset.Interf
|
|||
if kubeClient == nil {
|
||||
return secret, fmt.Errorf("Cannot get kube client")
|
||||
}
|
||||
secrets, err := kubeClient.Core().Secrets(pod.Namespace).Get(secretName, metav1.GetOptions{})
|
||||
secrets, err := kubeClient.CoreV1().Secrets(pod.Namespace).Get(secretName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return secret, err
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ func GetSecretForPV(secretNamespace, secretName, volumePluginName string, kubeCl
|
|||
if kubeClient == nil {
|
||||
return secret, fmt.Errorf("Cannot get kube client")
|
||||
}
|
||||
secrets, err := kubeClient.Core().Secrets(secretNamespace).Get(secretName, metav1.GetOptions{})
|
||||
secrets, err := kubeClient.CoreV1().Secrets(secretNamespace).Get(secretName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return secret, err
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ func LoadPodFromFile(filePath string) (*v1.Pod, error) {
|
|||
}
|
||||
pod := &v1.Pod{}
|
||||
|
||||
codec := api.Codecs.LegacyCodec(api.Registry.GroupOrDie(v1.GroupName).GroupVersion)
|
||||
codec := legacyscheme.Codecs.LegacyCodec(legacyscheme.Registry.GroupOrDie(v1.GroupName).GroupVersion)
|
||||
if err := runtime.DecodeInto(codec, podDef, pod); err != nil {
|
||||
return nil, fmt.Errorf("failed decoding file: %v", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue