Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
60943a7a
Unverified
Commit
60943a7a
authored
Feb 14, 2019
by
Kubernetes Prow Robot
Committed by
GitHub
Feb 14, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #69830 from davidz627/feature/csiTranslationMigration
In-Tree to CSI Migration logic for PersistentVolume Attach/Detach
parents
49e83f89
5dde1df1
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
136 additions
and
40 deletions
+136
-40
.import-restrictions
pkg/controller/.import-restrictions
+12
-2
csi_attacher.go
pkg/volume/csi/csi_attacher.go
+37
-9
csi_attacher_test.go
pkg/volume/csi/csi_attacher_test.go
+2
-2
csi_block.go
pkg/volume/csi/csi_block.go
+3
-3
csi_mounter.go
pkg/volume/csi/csi_mounter.go
+1
-1
csi_mounter_test.go
pkg/volume/csi/csi_mounter_test.go
+1
-1
csi_plugin.go
pkg/volume/csi/csi_plugin.go
+3
-2
csi_plugin_test.go
pkg/volume/csi/csi_plugin_test.go
+2
-2
csi_util.go
pkg/volume/csi/csi_util.go
+3
-3
BUILD
pkg/volume/util/operationexecutor/BUILD
+1
-0
operation_generator.go
pkg/volume/util/operationexecutor/operation_generator.go
+71
-15
No files found.
pkg/controller/.import-restrictions
View file @
60943a7a
...
@@ -101,7 +101,13 @@
...
@@ -101,7 +101,13 @@
"github.com/google/gofuzz",
"github.com/google/gofuzz",
"github.com/prometheus/client_golang/prometheus",
"github.com/prometheus/client_golang/prometheus",
"github.com/robfig/cron",
"github.com/robfig/cron",
"github.com/spf13/pflag"
"github.com/spf13/pflag",
"github.com/stretchr/testify/assert",
"github.com/stretchr/testify/require",
"github.com/google/gofuzz",
"github.com/golang/protobuf/ptypes/wrappers",
"github.com/golang/protobuf/proto",
"github.com/container-storage-interface/spec/lib/go/csi"
]
]
},
},
{
{
...
@@ -257,6 +263,8 @@
...
@@ -257,6 +263,8 @@
"AllowedPrefixes": [
"AllowedPrefixes": [
"k8s.io/csi-api/pkg/apis/csi/v1alpha1",
"k8s.io/csi-api/pkg/apis/csi/v1alpha1",
"k8s.io/csi-api/pkg/client/clientset/versioned",
"k8s.io/csi-api/pkg/client/clientset/versioned",
"k8s.io/csi-api/pkg/client/listers/csi/v1alpha1",
"k8s.io/csi-api/pkg/client/informers/externalversions",
"k8s.io/heapster/metrics/api/v1/types",
"k8s.io/heapster/metrics/api/v1/types",
"k8s.io/kube-controller-manager/config/v1alpha1",
"k8s.io/kube-controller-manager/config/v1alpha1",
"k8s.io/metrics/pkg/apis/custom_metrics/v1beta2",
"k8s.io/metrics/pkg/apis/custom_metrics/v1beta2",
...
@@ -288,7 +296,9 @@
...
@@ -288,7 +296,9 @@
"google.golang.org/api/compute/v0.alpha",
"google.golang.org/api/compute/v0.alpha",
"google.golang.org/api/container/v1",
"google.golang.org/api/container/v1",
"google.golang.org/api/compute/v0.beta",
"google.golang.org/api/compute/v0.beta",
"google.golang.org/api/tpu/v1"
"google.golang.org/api/tpu/v1",
"golang.org/x/net/context",
"google.golang.org/grpc"
]
]
}
}
]
]
...
...
pkg/volume/csi/csi_attacher.go
View file @
60943a7a
...
@@ -385,20 +385,38 @@ var _ volume.Detacher = &csiAttacher{}
...
@@ -385,20 +385,38 @@ var _ volume.Detacher = &csiAttacher{}
var
_
volume
.
DeviceUnmounter
=
&
csiAttacher
{}
var
_
volume
.
DeviceUnmounter
=
&
csiAttacher
{}
func
(
c
*
csiAttacher
)
Detach
(
volumeName
string
,
nodeName
types
.
NodeName
)
error
{
func
(
c
*
csiAttacher
)
Detach
(
volumeName
string
,
nodeName
types
.
NodeName
)
error
{
// volumeName in format driverName<SEP>volumeHandle generated by plugin.GetVolumeName()
var
attachID
string
var
volID
string
if
volumeName
==
""
{
if
volumeName
==
""
{
klog
.
Error
(
log
(
"detacher.Detach missing value for parameter volumeName"
))
klog
.
Error
(
log
(
"detacher.Detach missing value for parameter volumeName"
))
return
errors
.
New
(
"missing expected parameter volumeName"
)
return
errors
.
New
(
"missing expected parameter volumeName"
)
}
}
parts
:=
strings
.
Split
(
volumeName
,
volNameSep
)
if
len
(
parts
)
!=
2
{
if
isAttachmentName
(
volumeName
)
{
klog
.
Error
(
log
(
"detacher.Detach insufficient info encoded in volumeName"
))
// Detach can also be called with the attach ID as the `volumeName`. This codepath is
return
errors
.
New
(
"volumeName missing expected data"
)
// hit only when we have migrated an in-tree volume to CSI and the A/D Controller is shut
// down, the pod with the volume is deleted, and the A/D Controller starts back up in that
// order.
attachID
=
volumeName
// Vol ID should be the volume handle, except that is not available here.
// It is only used in log messages so in the event that this happens log messages will be
// printing out the attachID instead of the volume handle.
volID
=
volumeName
}
else
{
// volumeName in format driverName<SEP>volumeHandle generated by plugin.GetVolumeName()
parts
:=
strings
.
Split
(
volumeName
,
volNameSep
)
if
len
(
parts
)
!=
2
{
klog
.
Error
(
log
(
"detacher.Detach insufficient info encoded in volumeName"
))
return
errors
.
New
(
"volumeName missing expected data"
)
}
driverName
:=
parts
[
0
]
volID
=
parts
[
1
]
attachID
=
getAttachmentName
(
volID
,
driverName
,
string
(
nodeName
))
}
}
driverName
:=
parts
[
0
]
volID
:=
parts
[
1
]
attachID
:=
getAttachmentName
(
volID
,
driverName
,
string
(
nodeName
))
if
err
:=
c
.
k8s
.
StorageV1beta1
()
.
VolumeAttachments
()
.
Delete
(
attachID
,
nil
);
err
!=
nil
{
if
err
:=
c
.
k8s
.
StorageV1beta1
()
.
VolumeAttachments
()
.
Delete
(
attachID
,
nil
);
err
!=
nil
{
if
apierrs
.
IsNotFound
(
err
)
{
if
apierrs
.
IsNotFound
(
err
)
{
// object deleted or never existed, done
// object deleted or never existed, done
...
@@ -550,12 +568,22 @@ func (c *csiAttacher) UnmountDevice(deviceMountPath string) error {
...
@@ -550,12 +568,22 @@ func (c *csiAttacher) UnmountDevice(deviceMountPath string) error {
return
nil
return
nil
}
}
// getAttachmentName returns csi-<sha25
2(volName,csiDriverName,NodeName
>
// getAttachmentName returns csi-<sha25
6(volName,csiDriverName,NodeName)
>
func
getAttachmentName
(
volName
,
csiDriverName
,
nodeName
string
)
string
{
func
getAttachmentName
(
volName
,
csiDriverName
,
nodeName
string
)
string
{
result
:=
sha256
.
Sum256
([]
byte
(
fmt
.
Sprintf
(
"%s%s%s"
,
volName
,
csiDriverName
,
nodeName
)))
result
:=
sha256
.
Sum256
([]
byte
(
fmt
.
Sprintf
(
"%s%s%s"
,
volName
,
csiDriverName
,
nodeName
)))
return
fmt
.
Sprintf
(
"csi-%x"
,
result
)
return
fmt
.
Sprintf
(
"csi-%x"
,
result
)
}
}
// isAttachmentName returns true if the string given is of the form of an Attach ID
// and false otherwise
func
isAttachmentName
(
unknownString
string
)
bool
{
// 68 == "csi-" + len(sha256hash)
if
strings
.
HasPrefix
(
unknownString
,
"csi-"
)
&&
len
(
unknownString
)
==
68
{
return
true
}
return
false
}
func
makeDeviceMountPath
(
plugin
*
csiPlugin
,
spec
*
volume
.
Spec
)
(
string
,
error
)
{
func
makeDeviceMountPath
(
plugin
*
csiPlugin
,
spec
*
volume
.
Spec
)
(
string
,
error
)
{
if
spec
==
nil
{
if
spec
==
nil
{
return
""
,
fmt
.
Errorf
(
"makeDeviceMountPath failed, spec is nil"
)
return
""
,
fmt
.
Errorf
(
"makeDeviceMountPath failed, spec is nil"
)
...
...
pkg/volume/csi/csi_attacher_test.go
View file @
60943a7a
...
@@ -1004,9 +1004,9 @@ func newTestWatchPlugin(t *testing.T, csiClient *fakecsi.Clientset) (*csiPlugin,
...
@@ -1004,9 +1004,9 @@ func newTestWatchPlugin(t *testing.T, csiClient *fakecsi.Clientset) (*csiPlugin,
plugMgr
:=
&
volume
.
VolumePluginMgr
{}
plugMgr
:=
&
volume
.
VolumePluginMgr
{}
plugMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
nil
/* prober */
,
host
)
plugMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
nil
/* prober */
,
host
)
plug
,
err
:=
plugMgr
.
FindPluginByName
(
csi
PluginName
)
plug
,
err
:=
plugMgr
.
FindPluginByName
(
CSI
PluginName
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"can't find plugin %v"
,
csi
PluginName
)
t
.
Fatalf
(
"can't find plugin %v"
,
CSI
PluginName
)
}
}
csiPlug
,
ok
:=
plug
.
(
*
csiPlugin
)
csiPlug
,
ok
:=
plug
.
(
*
csiPlugin
)
...
...
pkg/volume/csi/csi_block.go
View file @
60943a7a
...
@@ -63,20 +63,20 @@ func (m *csiBlockMapper) GetGlobalMapPath(spec *volume.Spec) (string, error) {
...
@@ -63,20 +63,20 @@ func (m *csiBlockMapper) GetGlobalMapPath(spec *volume.Spec) (string, error) {
// Example: plugins/kubernetes.io/csi/volumeDevices/staging/{pvname}
// Example: plugins/kubernetes.io/csi/volumeDevices/staging/{pvname}
func
(
m
*
csiBlockMapper
)
getStagingPath
()
string
{
func
(
m
*
csiBlockMapper
)
getStagingPath
()
string
{
sanitizedSpecVolID
:=
utilstrings
.
EscapeQualifiedName
(
m
.
specName
)
sanitizedSpecVolID
:=
utilstrings
.
EscapeQualifiedName
(
m
.
specName
)
return
path
.
Join
(
m
.
plugin
.
host
.
GetVolumeDevicePluginDir
(
csi
PluginName
),
"staging"
,
sanitizedSpecVolID
)
return
path
.
Join
(
m
.
plugin
.
host
.
GetVolumeDevicePluginDir
(
CSI
PluginName
),
"staging"
,
sanitizedSpecVolID
)
}
}
// getPublishPath returns a publish path for a file (on the node) that should be used on NodePublishVolume/NodeUnpublishVolume
// getPublishPath returns a publish path for a file (on the node) that should be used on NodePublishVolume/NodeUnpublishVolume
// Example: plugins/kubernetes.io/csi/volumeDevices/publish/{pvname}
// Example: plugins/kubernetes.io/csi/volumeDevices/publish/{pvname}
func
(
m
*
csiBlockMapper
)
getPublishPath
()
string
{
func
(
m
*
csiBlockMapper
)
getPublishPath
()
string
{
sanitizedSpecVolID
:=
utilstrings
.
EscapeQualifiedName
(
m
.
specName
)
sanitizedSpecVolID
:=
utilstrings
.
EscapeQualifiedName
(
m
.
specName
)
return
path
.
Join
(
m
.
plugin
.
host
.
GetVolumeDevicePluginDir
(
csi
PluginName
),
"publish"
,
sanitizedSpecVolID
)
return
path
.
Join
(
m
.
plugin
.
host
.
GetVolumeDevicePluginDir
(
CSI
PluginName
),
"publish"
,
sanitizedSpecVolID
)
}
}
// GetPodDeviceMapPath returns pod's device file which will be mapped to a volume
// GetPodDeviceMapPath returns pod's device file which will be mapped to a volume
// returns: pods/{podUid}/volumeDevices/kubernetes.io~csi, {pvname}
// returns: pods/{podUid}/volumeDevices/kubernetes.io~csi, {pvname}
func
(
m
*
csiBlockMapper
)
GetPodDeviceMapPath
()
(
string
,
string
)
{
func
(
m
*
csiBlockMapper
)
GetPodDeviceMapPath
()
(
string
,
string
)
{
path
:=
m
.
plugin
.
host
.
GetPodVolumeDeviceDir
(
m
.
podUID
,
utilstrings
.
EscapeQualifiedName
(
csi
PluginName
))
path
:=
m
.
plugin
.
host
.
GetPodVolumeDeviceDir
(
m
.
podUID
,
utilstrings
.
EscapeQualifiedName
(
CSI
PluginName
))
specName
:=
m
.
specName
specName
:=
m
.
specName
klog
.
V
(
4
)
.
Infof
(
log
(
"blockMapper.GetPodDeviceMapPath [path=%s; name=%s]"
,
path
,
specName
))
klog
.
V
(
4
)
.
Infof
(
log
(
"blockMapper.GetPodDeviceMapPath [path=%s; name=%s]"
,
path
,
specName
))
return
path
,
specName
return
path
,
specName
...
...
pkg/volume/csi/csi_mounter.go
View file @
60943a7a
...
@@ -80,7 +80,7 @@ func (c *csiMountMgr) GetPath() string {
...
@@ -80,7 +80,7 @@ func (c *csiMountMgr) GetPath() string {
func
getTargetPath
(
uid
types
.
UID
,
specVolumeID
string
,
host
volume
.
VolumeHost
)
string
{
func
getTargetPath
(
uid
types
.
UID
,
specVolumeID
string
,
host
volume
.
VolumeHost
)
string
{
specVolID
:=
utilstrings
.
EscapeQualifiedName
(
specVolumeID
)
specVolID
:=
utilstrings
.
EscapeQualifiedName
(
specVolumeID
)
return
host
.
GetPodVolumeDir
(
uid
,
utilstrings
.
EscapeQualifiedName
(
csi
PluginName
),
specVolID
)
return
host
.
GetPodVolumeDir
(
uid
,
utilstrings
.
EscapeQualifiedName
(
CSI
PluginName
),
specVolID
)
}
}
// volume.Mounter methods
// volume.Mounter methods
...
...
pkg/volume/csi/csi_mounter_test.go
View file @
60943a7a
...
@@ -197,7 +197,7 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) {
...
@@ -197,7 +197,7 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) {
},
},
Spec
:
storage
.
VolumeAttachmentSpec
{
Spec
:
storage
.
VolumeAttachmentSpec
{
NodeName
:
"test-node"
,
NodeName
:
"test-node"
,
Attacher
:
csi
PluginName
,
Attacher
:
CSI
PluginName
,
Source
:
storage
.
VolumeAttachmentSource
{
Source
:
storage
.
VolumeAttachmentSource
{
PersistentVolumeName
:
&
pvName
,
PersistentVolumeName
:
&
pvName
,
},
},
...
...
pkg/volume/csi/csi_plugin.go
View file @
60943a7a
...
@@ -46,7 +46,8 @@ import (
...
@@ -46,7 +46,8 @@ import (
)
)
const
(
const
(
csiPluginName
=
"kubernetes.io/csi"
// CSIPluginName is the name of the in-tree CSI Plugin
CSIPluginName
=
"kubernetes.io/csi"
// TODO (vladimirvivien) implement a more dynamic way to discover
// TODO (vladimirvivien) implement a more dynamic way to discover
// the unix domain socket path for each installed csi driver.
// the unix domain socket path for each installed csi driver.
...
@@ -230,7 +231,7 @@ func (p *csiPlugin) Init(host volume.VolumeHost) error {
...
@@ -230,7 +231,7 @@ func (p *csiPlugin) Init(host volume.VolumeHost) error {
}
}
func
(
p
*
csiPlugin
)
GetPluginName
()
string
{
func
(
p
*
csiPlugin
)
GetPluginName
()
string
{
return
csi
PluginName
return
CSI
PluginName
}
}
// GetvolumeName returns a concatenated string of CSIVolumeSource.Driver<volNameSe>CSIVolumeSource.VolumeHandle
// GetvolumeName returns a concatenated string of CSIVolumeSource.Driver<volNameSe>CSIVolumeSource.VolumeHandle
...
...
pkg/volume/csi/csi_plugin_test.go
View file @
60943a7a
...
@@ -61,9 +61,9 @@ func newTestPlugin(t *testing.T, client *fakeclient.Clientset, csiClient *fakecs
...
@@ -61,9 +61,9 @@ func newTestPlugin(t *testing.T, client *fakeclient.Clientset, csiClient *fakecs
plugMgr
:=
&
volume
.
VolumePluginMgr
{}
plugMgr
:=
&
volume
.
VolumePluginMgr
{}
plugMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
nil
/* prober */
,
host
)
plugMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
nil
/* prober */
,
host
)
plug
,
err
:=
plugMgr
.
FindPluginByName
(
csi
PluginName
)
plug
,
err
:=
plugMgr
.
FindPluginByName
(
CSI
PluginName
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"can't find plugin %v"
,
csi
PluginName
)
t
.
Fatalf
(
"can't find plugin %v"
,
CSI
PluginName
)
}
}
csiPlug
,
ok
:=
plug
.
(
*
csiPlugin
)
csiPlug
,
ok
:=
plug
.
(
*
csiPlugin
)
...
...
pkg/volume/csi/csi_util.go
View file @
60943a7a
...
@@ -109,7 +109,7 @@ func getReadOnlyFromSpec(spec *volume.Spec) (bool, error) {
...
@@ -109,7 +109,7 @@ func getReadOnlyFromSpec(spec *volume.Spec) (bool, error) {
// log prepends log string with `kubernetes.io/csi`
// log prepends log string with `kubernetes.io/csi`
func
log
(
msg
string
,
parts
...
interface
{})
string
{
func
log
(
msg
string
,
parts
...
interface
{})
string
{
return
fmt
.
Sprintf
(
fmt
.
Sprintf
(
"%s: %s"
,
csi
PluginName
,
msg
),
parts
...
)
return
fmt
.
Sprintf
(
fmt
.
Sprintf
(
"%s: %s"
,
CSI
PluginName
,
msg
),
parts
...
)
}
}
// getVolumeDevicePluginDir returns the path where the CSI plugin keeps the
// getVolumeDevicePluginDir returns the path where the CSI plugin keeps the
...
@@ -117,7 +117,7 @@ func log(msg string, parts ...interface{}) string {
...
@@ -117,7 +117,7 @@ func log(msg string, parts ...interface{}) string {
// path: plugins/kubernetes.io/csi/volumeDevices/{specVolumeID}/dev
// path: plugins/kubernetes.io/csi/volumeDevices/{specVolumeID}/dev
func
getVolumeDevicePluginDir
(
specVolID
string
,
host
volume
.
VolumeHost
)
string
{
func
getVolumeDevicePluginDir
(
specVolID
string
,
host
volume
.
VolumeHost
)
string
{
sanitizedSpecVolID
:=
utilstrings
.
EscapeQualifiedName
(
specVolID
)
sanitizedSpecVolID
:=
utilstrings
.
EscapeQualifiedName
(
specVolID
)
return
path
.
Join
(
host
.
GetVolumeDevicePluginDir
(
csi
PluginName
),
sanitizedSpecVolID
,
"dev"
)
return
path
.
Join
(
host
.
GetVolumeDevicePluginDir
(
CSI
PluginName
),
sanitizedSpecVolID
,
"dev"
)
}
}
// getVolumeDeviceDataDir returns the path where the CSI plugin keeps the
// getVolumeDeviceDataDir returns the path where the CSI plugin keeps the
...
@@ -125,7 +125,7 @@ func getVolumeDevicePluginDir(specVolID string, host volume.VolumeHost) string {
...
@@ -125,7 +125,7 @@ func getVolumeDevicePluginDir(specVolID string, host volume.VolumeHost) string {
// path: plugins/kubernetes.io/csi/volumeDevices/{specVolumeID}/data
// path: plugins/kubernetes.io/csi/volumeDevices/{specVolumeID}/data
func
getVolumeDeviceDataDir
(
specVolID
string
,
host
volume
.
VolumeHost
)
string
{
func
getVolumeDeviceDataDir
(
specVolID
string
,
host
volume
.
VolumeHost
)
string
{
sanitizedSpecVolID
:=
utilstrings
.
EscapeQualifiedName
(
specVolID
)
sanitizedSpecVolID
:=
utilstrings
.
EscapeQualifiedName
(
specVolID
)
return
path
.
Join
(
host
.
GetVolumeDevicePluginDir
(
csi
PluginName
),
sanitizedSpecVolID
,
"data"
)
return
path
.
Join
(
host
.
GetVolumeDevicePluginDir
(
CSI
PluginName
),
sanitizedSpecVolID
,
"data"
)
}
}
// hasReadWriteOnce returns true if modes contains v1.ReadWriteOnce
// hasReadWriteOnce returns true if modes contains v1.ReadWriteOnce
...
...
pkg/volume/util/operationexecutor/BUILD
View file @
60943a7a
...
@@ -19,6 +19,7 @@ go_library(
...
@@ -19,6 +19,7 @@ go_library(
"//pkg/kubelet/events:go_default_library",
"//pkg/kubelet/events:go_default_library",
"//pkg/util/mount:go_default_library",
"//pkg/util/mount:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/csi:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/util/nestedpendingoperations:go_default_library",
"//pkg/volume/util/nestedpendingoperations:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/types:go_default_library",
...
...
pkg/volume/util/operationexecutor/operation_generator.go
View file @
60943a7a
...
@@ -37,6 +37,7 @@ import (
...
@@ -37,6 +37,7 @@ import (
kevents
"k8s.io/kubernetes/pkg/kubelet/events"
kevents
"k8s.io/kubernetes/pkg/kubelet/events"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/csi"
"k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util"
volumetypes
"k8s.io/kubernetes/pkg/volume/util/types"
volumetypes
"k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
...
@@ -289,6 +290,9 @@ func (og *operationGenerator) GenerateBulkVolumeVerifyFunc(
...
@@ -289,6 +290,9 @@ func (og *operationGenerator) GenerateBulkVolumeVerifyFunc(
func
(
og
*
operationGenerator
)
GenerateAttachVolumeFunc
(
func
(
og
*
operationGenerator
)
GenerateAttachVolumeFunc
(
volumeToAttach
VolumeToAttach
,
volumeToAttach
VolumeToAttach
,
actualStateOfWorld
ActualStateOfWorldAttacherUpdater
)
(
volumetypes
.
GeneratedOperations
,
error
)
{
actualStateOfWorld
ActualStateOfWorldAttacherUpdater
)
(
volumetypes
.
GeneratedOperations
,
error
)
{
var
err
error
var
attachableVolumePlugin
volume
.
AttachableVolumePlugin
// Get attacher plugin
// Get attacher plugin
eventRecorderFunc
:=
func
(
err
*
error
)
{
eventRecorderFunc
:=
func
(
err
*
error
)
{
if
*
err
!=
nil
{
if
*
err
!=
nil
{
...
@@ -298,11 +302,29 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
...
@@ -298,11 +302,29 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
}
}
}
}
attachableVolumePlugin
,
err
:=
originalSpec
:=
volumeToAttach
.
VolumeSpec
og
.
volumePluginMgr
.
FindAttachablePluginBySpec
(
volumeToAttach
.
VolumeSpec
)
// useCSIPlugin will check both CSIMigration and the plugin specific feature gate
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
if
useCSIPlugin
(
og
.
volumePluginMgr
,
volumeToAttach
.
VolumeSpec
)
{
eventRecorderFunc
(
&
err
)
// The volume represented by this spec is CSI and thus should be migrated
return
volumetypes
.
GeneratedOperations
{},
volumeToAttach
.
GenerateErrorDetailed
(
"AttachVolume.FindAttachablePluginBySpec failed"
,
err
)
attachableVolumePlugin
,
err
=
og
.
volumePluginMgr
.
FindAttachablePluginByName
(
csi
.
CSIPluginName
)
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
eventRecorderFunc
(
&
err
)
return
volumetypes
.
GeneratedOperations
{},
volumeToAttach
.
GenerateErrorDetailed
(
"AttachVolume.FindAttachablePluginByName failed"
,
err
)
}
csiSpec
,
err
:=
translateSpec
(
volumeToAttach
.
VolumeSpec
)
if
err
!=
nil
{
return
volumetypes
.
GeneratedOperations
{},
volumeToAttach
.
GenerateErrorDetailed
(
"AttachVolume.TranslateSpec failed"
,
err
)
}
volumeToAttach
.
VolumeSpec
=
csiSpec
}
else
{
attachableVolumePlugin
,
err
=
og
.
volumePluginMgr
.
FindAttachablePluginBySpec
(
volumeToAttach
.
VolumeSpec
)
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
eventRecorderFunc
(
&
err
)
return
volumetypes
.
GeneratedOperations
{},
volumeToAttach
.
GenerateErrorDetailed
(
"AttachVolume.FindAttachablePluginBySpec failed"
,
err
)
}
}
}
volumeAttacher
,
newAttacherErr
:=
attachableVolumePlugin
.
NewAttacher
()
volumeAttacher
,
newAttacherErr
:=
attachableVolumePlugin
.
NewAttacher
()
...
@@ -320,7 +342,7 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
...
@@ -320,7 +342,7 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
if
derr
,
ok
:=
attachErr
.
(
*
volerr
.
DanglingAttachError
);
ok
{
if
derr
,
ok
:=
attachErr
.
(
*
volerr
.
DanglingAttachError
);
ok
{
addErr
:=
actualStateOfWorld
.
MarkVolumeAsAttached
(
addErr
:=
actualStateOfWorld
.
MarkVolumeAsAttached
(
v1
.
UniqueVolumeName
(
""
),
v1
.
UniqueVolumeName
(
""
),
volumeToAttach
.
Volume
Spec
,
original
Spec
,
derr
.
CurrentNode
,
derr
.
CurrentNode
,
derr
.
DevicePath
)
derr
.
DevicePath
)
...
@@ -330,7 +352,7 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
...
@@ -330,7 +352,7 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
}
else
{
}
else
{
addErr
:=
actualStateOfWorld
.
MarkVolumeAsUncertain
(
addErr
:=
actualStateOfWorld
.
MarkVolumeAsUncertain
(
v1
.
UniqueVolumeName
(
""
),
volumeToAttach
.
Volume
Spec
,
volumeToAttach
.
NodeName
)
v1
.
UniqueVolumeName
(
""
),
original
Spec
,
volumeToAttach
.
NodeName
)
if
addErr
!=
nil
{
if
addErr
!=
nil
{
klog
.
Errorf
(
"AttachVolume.MarkVolumeAsUncertain fail to add the volume %q to actual state with %s"
,
volumeToAttach
.
VolumeName
,
addErr
)
klog
.
Errorf
(
"AttachVolume.MarkVolumeAsUncertain fail to add the volume %q to actual state with %s"
,
volumeToAttach
.
VolumeName
,
addErr
)
}
}
...
@@ -348,7 +370,7 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
...
@@ -348,7 +370,7 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
// Update actual state of world
// Update actual state of world
addVolumeNodeErr
:=
actualStateOfWorld
.
MarkVolumeAsAttached
(
addVolumeNodeErr
:=
actualStateOfWorld
.
MarkVolumeAsAttached
(
v1
.
UniqueVolumeName
(
""
),
volumeToAttach
.
Volume
Spec
,
volumeToAttach
.
NodeName
,
devicePath
)
v1
.
UniqueVolumeName
(
""
),
original
Spec
,
volumeToAttach
.
NodeName
,
devicePath
)
if
addVolumeNodeErr
!=
nil
{
if
addVolumeNodeErr
!=
nil
{
// On failure, return error. Caller will log and retry.
// On failure, return error. Caller will log and retry.
return
volumeToAttach
.
GenerateError
(
"AttachVolume.MarkVolumeAsAttached failed"
,
addVolumeNodeErr
)
return
volumeToAttach
.
GenerateError
(
"AttachVolume.MarkVolumeAsAttached failed"
,
addVolumeNodeErr
)
...
@@ -379,10 +401,26 @@ func (og *operationGenerator) GenerateDetachVolumeFunc(
...
@@ -379,10 +401,26 @@ func (og *operationGenerator) GenerateDetachVolumeFunc(
if
volumeToDetach
.
VolumeSpec
!=
nil
{
if
volumeToDetach
.
VolumeSpec
!=
nil
{
// Get attacher plugin
// Get attacher plugin
attachableVolumePlugin
,
err
=
// useCSIPlugin will check both CSIMigration and the plugin specific feature gate
og
.
volumePluginMgr
.
FindAttachablePluginBySpec
(
volumeToDetach
.
VolumeSpec
)
if
useCSIPlugin
(
og
.
volumePluginMgr
,
volumeToDetach
.
VolumeSpec
)
{
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
// The volume represented by this spec is CSI and thus should be migrated
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"DetachVolume.FindAttachablePluginBySpec failed"
,
err
)
attachableVolumePlugin
,
err
=
og
.
volumePluginMgr
.
FindAttachablePluginByName
(
csi
.
CSIPluginName
)
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"AttachVolume.FindAttachablePluginBySpec failed"
,
err
)
}
csiSpec
,
err
:=
translateSpec
(
volumeToDetach
.
VolumeSpec
)
if
err
!=
nil
{
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"AttachVolume.TranslateSpec failed"
,
err
)
}
volumeToDetach
.
VolumeSpec
=
csiSpec
}
else
{
attachableVolumePlugin
,
err
=
og
.
volumePluginMgr
.
FindAttachablePluginBySpec
(
volumeToDetach
.
VolumeSpec
)
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"DetachVolume.FindAttachablePluginBySpec failed"
,
err
)
}
}
}
volumeName
,
err
=
volumeName
,
err
=
...
@@ -398,10 +436,28 @@ func (og *operationGenerator) GenerateDetachVolumeFunc(
...
@@ -398,10 +436,28 @@ func (og *operationGenerator) GenerateDetachVolumeFunc(
if
err
!=
nil
{
if
err
!=
nil
{
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"DetachVolume.SplitUniqueName failed"
,
err
)
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"DetachVolume.SplitUniqueName failed"
,
err
)
}
}
attachableVolumePlugin
,
err
=
og
.
volumePluginMgr
.
FindAttachablePluginByName
(
pluginName
)
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
// TODO(dyzz): This case can't distinguish between PV and In-line which is necessary because
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"DetachVolume.FindAttachablePluginByName failed"
,
err
)
// if it was PV it may have been migrated, but the same plugin with in-line may not have been.
// Suggestions welcome...
if
csilib
.
IsMigratableByName
(
pluginName
)
&&
utilfeature
.
DefaultFeatureGate
.
Enabled
(
features
.
CSIMigration
)
{
// The volume represented by this spec is CSI and thus should be migrated
attachableVolumePlugin
,
err
=
og
.
volumePluginMgr
.
FindAttachablePluginByName
(
csi
.
CSIPluginName
)
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"AttachVolume.FindAttachablePluginBySpec failed"
,
err
)
}
// volumeToDetach.VolumeName here is always the in-tree volume name
// therefore a workaround is required. volumeToDetach.DevicePath
// is the attachID which happens to be what volumeName is needed for in Detach.
// Therefore we set volumeName to the attachID. And CSI Detach can detect and use that.
volumeName
=
volumeToDetach
.
DevicePath
}
else
{
attachableVolumePlugin
,
err
=
og
.
volumePluginMgr
.
FindAttachablePluginByName
(
pluginName
)
if
err
!=
nil
||
attachableVolumePlugin
==
nil
{
return
volumetypes
.
GeneratedOperations
{},
volumeToDetach
.
GenerateErrorDetailed
(
"DetachVolume.FindAttachablePluginByName failed"
,
err
)
}
}
}
}
}
if
pluginName
==
""
{
if
pluginName
==
""
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment