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
52cb4c1d
Commit
52cb4c1d
authored
Jan 26, 2016
by
k8s-merge-robot
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #18445 from resouer/fix-emptydir
Auto commit by PR queue bot
parents
3f40fb7d
0fa5b6c4
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
334 additions
and
65 deletions
+334
-65
persistentvolume_provisioner_controller.go
...rsistentvolume/persistentvolume_provisioner_controller.go
+2
-2
persistentvolume_recycler_controller.go
.../persistentvolume/persistentvolume_recycler_controller.go
+2
-2
volumes.go
pkg/kubelet/volumes.go
+16
-4
downwardapi.go
pkg/volume/downwardapi/downwardapi.go
+15
-9
downwardapi_test.go
pkg/volume/downwardapi/downwardapi_test.go
+31
-11
git_repo.go
pkg/volume/git_repo/git_repo.go
+7
-7
git_repo_test.go
pkg/volume/git_repo/git_repo_test.go
+21
-5
persistent_claim.go
pkg/volume/persistent_claim/persistent_claim.go
+1
-1
plugins.go
pkg/volume/plugins.go
+2
-2
secret.go
pkg/volume/secret/secret.go
+28
-12
secret_test.go
pkg/volume/secret/secret_test.go
+15
-5
testing.go
pkg/volume/testing.go
+15
-5
empty_dir_wrapper.go
test/e2e/empty_dir_wrapper.go
+179
-0
No files found.
pkg/controller/persistentvolume/persistentvolume_provisioner_controller.go
View file @
52cb4c1d
...
...
@@ -473,11 +473,11 @@ func (c *PersistentVolumeProvisionerController) GetKubeClient() client.Interface
return
c
.
client
.
GetKubeClient
()
}
func
(
c
*
PersistentVolumeProvisionerController
)
NewWrapperBuilder
(
spec
*
volume
.
Spec
,
pod
*
api
.
Pod
,
opts
volume
.
VolumeOptions
)
(
volume
.
Builder
,
error
)
{
func
(
c
*
PersistentVolumeProvisionerController
)
NewWrapperBuilder
(
volName
string
,
spec
volume
.
Spec
,
pod
*
api
.
Pod
,
opts
volume
.
VolumeOptions
)
(
volume
.
Builder
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"NewWrapperBuilder not supported by PVClaimBinder's VolumeHost implementation"
)
}
func
(
c
*
PersistentVolumeProvisionerController
)
NewWrapperCleaner
(
spec
*
volume
.
Spec
,
podUID
types
.
UID
)
(
volume
.
Cleaner
,
error
)
{
func
(
c
*
PersistentVolumeProvisionerController
)
NewWrapperCleaner
(
volName
string
,
spec
volume
.
Spec
,
podUID
types
.
UID
)
(
volume
.
Cleaner
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"NewWrapperCleaner not supported by PVClaimBinder's VolumeHost implementation"
)
}
...
...
pkg/controller/persistentvolume/persistentvolume_recycler_controller.go
View file @
52cb4c1d
...
...
@@ -291,11 +291,11 @@ func (f *PersistentVolumeRecycler) GetKubeClient() client.Interface {
return
f
.
kubeClient
}
func
(
f
*
PersistentVolumeRecycler
)
NewWrapperBuilder
(
spec
*
volume
.
Spec
,
pod
*
api
.
Pod
,
opts
volume
.
VolumeOptions
)
(
volume
.
Builder
,
error
)
{
func
(
f
*
PersistentVolumeRecycler
)
NewWrapperBuilder
(
volName
string
,
spec
volume
.
Spec
,
pod
*
api
.
Pod
,
opts
volume
.
VolumeOptions
)
(
volume
.
Builder
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"NewWrapperBuilder not supported by PVClaimBinder's VolumeHost implementation"
)
}
func
(
f
*
PersistentVolumeRecycler
)
NewWrapperCleaner
(
spec
*
volume
.
Spec
,
podUID
types
.
UID
)
(
volume
.
Cleaner
,
error
)
{
func
(
f
*
PersistentVolumeRecycler
)
NewWrapperCleaner
(
volName
string
,
spec
volume
.
Spec
,
podUID
types
.
UID
)
(
volume
.
Cleaner
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"NewWrapperCleaner not supported by PVClaimBinder's VolumeHost implementation"
)
}
...
...
pkg/kubelet/volumes.go
View file @
52cb4c1d
...
...
@@ -58,16 +58,28 @@ func (vh *volumeHost) GetKubeClient() client.Interface {
return
vh
.
kubelet
.
kubeClient
}
func
(
vh
*
volumeHost
)
NewWrapperBuilder
(
spec
*
volume
.
Spec
,
pod
*
api
.
Pod
,
opts
volume
.
VolumeOptions
)
(
volume
.
Builder
,
error
)
{
b
,
err
:=
vh
.
kubelet
.
newVolumeBuilderFromPlugins
(
spec
,
pod
,
opts
)
func
(
vh
*
volumeHost
)
NewWrapperBuilder
(
volName
string
,
spec
volume
.
Spec
,
pod
*
api
.
Pod
,
opts
volume
.
VolumeOptions
)
(
volume
.
Builder
,
error
)
{
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName
:=
"wrapped_"
+
volName
if
spec
.
Volume
!=
nil
{
spec
.
Volume
.
Name
=
wrapperVolumeName
}
b
,
err
:=
vh
.
kubelet
.
newVolumeBuilderFromPlugins
(
&
spec
,
pod
,
opts
)
if
err
==
nil
&&
b
==
nil
{
return
nil
,
errUnsupportedVolumeType
}
return
b
,
nil
}
func
(
vh
*
volumeHost
)
NewWrapperCleaner
(
spec
*
volume
.
Spec
,
podUID
types
.
UID
)
(
volume
.
Cleaner
,
error
)
{
plugin
,
err
:=
vh
.
kubelet
.
volumePluginMgr
.
FindPluginBySpec
(
spec
)
func
(
vh
*
volumeHost
)
NewWrapperCleaner
(
volName
string
,
spec
volume
.
Spec
,
podUID
types
.
UID
)
(
volume
.
Cleaner
,
error
)
{
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName
:=
"wrapped_"
+
volName
if
spec
.
Volume
!=
nil
{
spec
.
Volume
.
Name
=
wrapperVolumeName
}
plugin
,
err
:=
vh
.
kubelet
.
volumePluginMgr
.
FindPluginBySpec
(
&
spec
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
pkg/volume/downwardapi/downwardapi.go
View file @
52cb4c1d
...
...
@@ -51,6 +51,10 @@ type downwardAPIPlugin struct {
var
_
volume
.
VolumePlugin
=
&
downwardAPIPlugin
{}
var
wrappedVolumeSpec
=
volume
.
Spec
{
Volume
:
&
api
.
Volume
{
VolumeSource
:
api
.
VolumeSource
{
EmptyDir
:
&
api
.
EmptyDirVolumeSource
{
Medium
:
api
.
StorageMediumMemory
}}},
}
func
(
plugin
*
downwardAPIPlugin
)
Init
(
host
volume
.
VolumeHost
)
error
{
plugin
.
host
=
host
return
nil
...
...
@@ -77,11 +81,18 @@ func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opt
}
return
&
downwardAPIVolumeBuilder
{
downwardAPIVolume
:
v
,
opts
:
&
opts
},
nil
opts
:
&
opts
,
},
nil
}
func
(
plugin
*
downwardAPIPlugin
)
NewCleaner
(
volName
string
,
podUID
types
.
UID
)
(
volume
.
Cleaner
,
error
)
{
return
&
downwardAPIVolumeCleaner
{
&
downwardAPIVolume
{
volName
:
volName
,
podUID
:
podUID
,
plugin
:
plugin
}},
nil
return
&
downwardAPIVolumeCleaner
{
&
downwardAPIVolume
{
volName
:
volName
,
podUID
:
podUID
,
plugin
:
plugin
,
},
},
nil
}
// downwardAPIVolume retrieves downward API data and placing them into the volume on the host.
...
...
@@ -94,11 +105,6 @@ type downwardAPIVolume struct {
volume
.
MetricsNil
}
// This is the spec for the volume that this plugin wraps.
var
wrappedVolumeSpec
=
&
volume
.
Spec
{
Volume
:
&
api
.
Volume
{
VolumeSource
:
api
.
VolumeSource
{
EmptyDir
:
&
api
.
EmptyDirVolumeSource
{
Medium
:
api
.
StorageMediumMemory
}}},
}
// downwardAPIVolumeBuilder fetches info from downward API from the pod
// and dumps it in files
type
downwardAPIVolumeBuilder
struct
{
...
...
@@ -130,7 +136,7 @@ func (b *downwardAPIVolumeBuilder) SetUp() error {
func
(
b
*
downwardAPIVolumeBuilder
)
SetUpAt
(
dir
string
)
error
{
glog
.
V
(
3
)
.
Infof
(
"Setting up a downwardAPI volume %v for pod %v/%v at %v"
,
b
.
volName
,
b
.
pod
.
Namespace
,
b
.
pod
.
Name
,
dir
)
// Wrap EmptyDir. Here we rely on the idempotency of the wrapped plugin to avoid repeatedly mounting
wrapped
,
err
:=
b
.
plugin
.
host
.
NewWrapperBuilder
(
wrappedVolumeSpec
,
b
.
pod
,
*
b
.
opts
)
wrapped
,
err
:=
b
.
plugin
.
host
.
NewWrapperBuilder
(
b
.
volName
,
wrappedVolumeSpec
,
b
.
pod
,
*
b
.
opts
)
if
err
!=
nil
{
glog
.
Errorf
(
"Couldn't setup downwardAPI volume %v for pod %v/%v: %s"
,
b
.
volName
,
b
.
pod
.
Namespace
,
b
.
pod
.
Name
,
err
.
Error
())
return
err
...
...
@@ -364,7 +370,7 @@ func (c *downwardAPIVolumeCleaner) TearDownAt(dir string) error {
glog
.
V
(
3
)
.
Infof
(
"Tearing down volume %v for pod %v at %v"
,
c
.
volName
,
c
.
podUID
,
dir
)
// Wrap EmptyDir, let it do the teardown.
wrapped
,
err
:=
c
.
plugin
.
host
.
NewWrapperCleaner
(
wrappedVolumeSpec
,
c
.
podUID
)
wrapped
,
err
:=
c
.
plugin
.
host
.
NewWrapperCleaner
(
c
.
volName
,
wrappedVolumeSpec
,
c
.
podUID
)
if
err
!=
nil
{
return
err
}
...
...
pkg/volume/downwardapi/downwardapi_test.go
View file @
52cb4c1d
...
...
@@ -39,12 +39,12 @@ func formatMap(m map[string]string) (fmtstr string) {
return
}
func
newTestHost
(
t
*
testing
.
T
,
client
client
.
Interface
,
basePath
string
)
volume
.
VolumeHost
{
func
newTestHost
(
t
*
testing
.
T
,
client
client
.
Interface
,
basePath
string
)
(
string
,
volume
.
VolumeHost
)
{
tempDir
,
err
:=
ioutil
.
TempDir
(
basePath
,
"downwardApi_volume_test."
)
if
err
!=
nil
{
t
.
Fatalf
(
"can't make a temp rootdir: %v"
,
err
)
}
return
volume
.
NewFakeVolumeHost
(
tempDir
,
client
,
empty_dir
.
ProbeVolumePlugins
())
return
tempDir
,
volume
.
NewFakeVolumeHost
(
tempDir
,
client
,
empty_dir
.
ProbeVolumePlugins
())
}
func
TestCanSupport
(
t
*
testing
.
T
)
{
...
...
@@ -54,7 +54,8 @@ func TestCanSupport(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
nil
,
tmpDir
))
_
,
host
:=
newTestHost
(
t
,
nil
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
if
err
!=
nil
{
...
...
@@ -110,7 +111,8 @@ func TestLabels(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
fake
,
tmpDir
))
rootDir
,
host
:=
newTestHost
(
t
,
fake
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
volumeSpec
:=
&
api
.
Volume
{
Name
:
testVolumeName
,
...
...
@@ -141,6 +143,17 @@ func TestLabels(t *testing.T) {
t
.
Errorf
(
"Failed to setup volume: %v"
,
err
)
}
// downwardAPI volume should create its own empty wrapper path
podWrapperMetadataDir
:=
fmt
.
Sprintf
(
"%v/pods/%v/plugins/kubernetes.io~empty-dir/wrapped_%v"
,
rootDir
,
testPodUID
,
testVolumeName
)
if
_
,
err
:=
os
.
Stat
(
podWrapperMetadataDir
);
err
!=
nil
{
if
os
.
IsNotExist
(
err
)
{
t
.
Errorf
(
"SetUp() failed, empty-dir wrapper path was not created: %s"
,
podWrapperMetadataDir
)
}
else
{
t
.
Errorf
(
"SetUp() failed: %v"
,
err
)
}
}
var
data
[]
byte
data
,
err
=
ioutil
.
ReadFile
(
path
.
Join
(
volumePath
,
"labels"
))
if
err
!=
nil
{
...
...
@@ -189,7 +202,8 @@ func TestAnnotations(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
fake
,
tmpDir
))
_
,
host
:=
newTestHost
(
t
,
fake
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
if
err
!=
nil
{
t
.
Errorf
(
"Can't find the plugin by name"
)
...
...
@@ -254,7 +268,8 @@ func TestName(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
fake
,
tmpDir
))
_
,
host
:=
newTestHost
(
t
,
fake
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
if
err
!=
nil
{
t
.
Errorf
(
"Can't find the plugin by name"
)
...
...
@@ -320,7 +335,8 @@ func TestNamespace(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
fake
,
tmpDir
))
_
,
host
:=
newTestHost
(
t
,
fake
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
if
err
!=
nil
{
t
.
Errorf
(
"Can't find the plugin by name"
)
...
...
@@ -379,7 +395,8 @@ func TestWriteTwiceNoUpdate(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
fake
,
tmpDir
))
_
,
host
:=
newTestHost
(
t
,
fake
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
volumeSpec
:=
&
api
.
Volume
{
Name
:
testVolumeName
,
...
...
@@ -468,7 +485,8 @@ func TestWriteTwiceWithUpdate(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
fake
,
tmpDir
))
_
,
host
:=
newTestHost
(
t
,
fake
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
volumeSpec
:=
&
api
.
Volume
{
Name
:
testVolumeName
,
...
...
@@ -577,7 +595,8 @@ func TestWriteWithUnixPath(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
fake
,
tmpDir
))
_
,
host
:=
newTestHost
(
t
,
fake
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
volumeSpec
:=
&
api
.
Volume
{
Name
:
testVolumeName
,
...
...
@@ -656,7 +675,8 @@ func TestWriteWithUnixPathBadPath(t *testing.T) {
}
defer
os
.
RemoveAll
(
tmpDir
)
pluginMgr
:=
volume
.
VolumePluginMgr
{}
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
,
fake
,
tmpDir
))
_
,
host
:=
newTestHost
(
t
,
fake
,
tmpDir
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plugin
,
err
:=
pluginMgr
.
FindPluginByName
(
downwardAPIPluginName
)
if
err
!=
nil
{
t
.
Errorf
(
"Can't find the plugin by name"
)
...
...
pkg/volume/git_repo/git_repo.go
View file @
52cb4c1d
...
...
@@ -41,6 +41,10 @@ type gitRepoPlugin struct {
var
_
volume
.
VolumePlugin
=
&
gitRepoPlugin
{}
var
wrappedVolumeSpec
=
volume
.
Spec
{
Volume
:
&
api
.
Volume
{
VolumeSource
:
api
.
VolumeSource
{
EmptyDir
:
&
api
.
EmptyDirVolumeSource
{}}},
}
const
(
gitRepoPluginName
=
"kubernetes.io/git-repo"
)
...
...
@@ -128,11 +132,6 @@ func (b *gitRepoVolumeBuilder) SetUp() error {
return
b
.
SetUpAt
(
b
.
GetPath
())
}
// This is the spec for the volume that this plugin wraps.
var
wrappedVolumeSpec
=
&
volume
.
Spec
{
Volume
:
&
api
.
Volume
{
VolumeSource
:
api
.
VolumeSource
{
EmptyDir
:
&
api
.
EmptyDirVolumeSource
{}}},
}
// SetUpAt creates new directory and clones a git repo.
func
(
b
*
gitRepoVolumeBuilder
)
SetUpAt
(
dir
string
)
error
{
if
volumeutil
.
IsReady
(
b
.
getMetaDir
())
{
...
...
@@ -140,7 +139,7 @@ func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error {
}
// Wrap EmptyDir, let it do the setup.
wrapped
,
err
:=
b
.
plugin
.
host
.
NewWrapperBuilder
(
wrappedVolumeSpec
,
&
b
.
pod
,
b
.
opts
)
wrapped
,
err
:=
b
.
plugin
.
host
.
NewWrapperBuilder
(
b
.
volName
,
wrappedVolumeSpec
,
&
b
.
pod
,
b
.
opts
)
if
err
!=
nil
{
return
err
}
...
...
@@ -218,8 +217,9 @@ func (c *gitRepoVolumeCleaner) TearDown() error {
// TearDownAt simply deletes everything in the directory.
func
(
c
*
gitRepoVolumeCleaner
)
TearDownAt
(
dir
string
)
error
{
// Wrap EmptyDir, let it do the teardown.
wrapped
,
err
:=
c
.
plugin
.
host
.
NewWrapperCleaner
(
wrappedVolumeSpec
,
c
.
podUID
)
wrapped
,
err
:=
c
.
plugin
.
host
.
NewWrapperCleaner
(
c
.
volName
,
wrappedVolumeSpec
,
c
.
podUID
)
if
err
!=
nil
{
return
err
}
...
...
pkg/volume/git_repo/git_repo_test.go
View file @
52cb4c1d
...
...
@@ -32,17 +32,18 @@ import (
"k8s.io/kubernetes/pkg/volume/empty_dir"
)
func
newTestHost
(
t
*
testing
.
T
)
volume
.
VolumeHost
{
func
newTestHost
(
t
*
testing
.
T
)
(
string
,
volume
.
VolumeHost
)
{
tempDir
,
err
:=
ioutil
.
TempDir
(
"/tmp"
,
"git_repo_test."
)
if
err
!=
nil
{
t
.
Fatalf
(
"can't make a temp rootdir: %v"
,
err
)
}
return
volume
.
NewFakeVolumeHost
(
tempDir
,
nil
,
empty_dir
.
ProbeVolumePlugins
())
return
tempDir
,
volume
.
NewFakeVolumeHost
(
tempDir
,
nil
,
empty_dir
.
ProbeVolumePlugins
())
}
func
TestCanSupport
(
t
*
testing
.
T
)
{
plugMgr
:=
volume
.
VolumePluginMgr
{}
plugMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
))
_
,
host
:=
newTestHost
(
t
)
plugMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plug
,
err
:=
plugMgr
.
FindPluginByName
(
"kubernetes.io/git-repo"
)
if
err
!=
nil
{
...
...
@@ -218,7 +219,8 @@ func doTestPlugin(scenario struct {
allErrs
:=
[]
error
{}
plugMgr
:=
volume
.
VolumePluginMgr
{}
plugMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
newTestHost
(
t
))
rootDir
,
host
:=
newTestHost
(
t
)
plugMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
plug
,
err
:=
plugMgr
.
FindPluginByName
(
"kubernetes.io/git-repo"
)
if
err
!=
nil
{
...
...
@@ -241,7 +243,8 @@ func doTestPlugin(scenario struct {
}
path
:=
builder
.
GetPath
()
if
!
strings
.
HasSuffix
(
path
,
"pods/poduid/volumes/kubernetes.io~git-repo/vol1"
)
{
suffix
:=
fmt
.
Sprintf
(
"pods/poduid/volumes/kubernetes.io~git-repo/%v"
,
scenario
.
vol
.
Name
)
if
!
strings
.
HasSuffix
(
path
,
suffix
)
{
allErrs
=
append
(
allErrs
,
fmt
.
Errorf
(
"Got unexpected path: %s"
,
path
))
return
allErrs
...
...
@@ -263,6 +266,19 @@ func doTestPlugin(scenario struct {
}
}
// gitRepo volume should create its own empty wrapper path
podWrapperMetadataDir
:=
fmt
.
Sprintf
(
"%v/pods/poduid/plugins/kubernetes.io~empty-dir/wrapped_%v"
,
rootDir
,
scenario
.
vol
.
Name
)
if
_
,
err
:=
os
.
Stat
(
podWrapperMetadataDir
);
err
!=
nil
{
if
os
.
IsNotExist
(
err
)
{
allErrs
=
append
(
allErrs
,
fmt
.
Errorf
(
"SetUp() failed, empty-dir wrapper path is not created: %s"
,
podWrapperMetadataDir
))
}
else
{
allErrs
=
append
(
allErrs
,
fmt
.
Errorf
(
"SetUp() failed: %v"
,
err
))
}
}
cleaner
,
err
:=
plug
.
NewCleaner
(
"vol1"
,
types
.
UID
(
"poduid"
))
if
err
!=
nil
{
allErrs
=
append
(
allErrs
,
...
...
pkg/volume/persistent_claim/persistent_claim.go
View file @
52cb4c1d
...
...
@@ -80,7 +80,7 @@ func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod,
return
nil
,
err
}
builder
,
err
:=
plugin
.
host
.
NewWrapperBuilder
(
volume
.
NewSpecFromPersistentVolume
(
pv
,
spec
.
ReadOnly
),
pod
,
opts
)
builder
,
err
:=
plugin
.
host
.
NewWrapperBuilder
(
claim
.
Spec
.
VolumeName
,
*
volume
.
NewSpecFromPersistentVolume
(
pv
,
spec
.
ReadOnly
),
pod
,
opts
)
if
err
!=
nil
{
glog
.
Errorf
(
"Error creating builder for claim: %+v
\n
"
,
claim
.
Name
)
return
nil
,
err
...
...
pkg/volume/plugins.go
View file @
52cb4c1d
...
...
@@ -144,12 +144,12 @@ type VolumeHost interface {
// the provided spec. This is used to implement volume plugins which
// "wrap" other plugins. For example, the "secret" volume is
// implemented in terms of the "emptyDir" volume.
NewWrapperBuilder
(
spec
*
Spec
,
pod
*
api
.
Pod
,
opts
VolumeOptions
)
(
Builder
,
error
)
NewWrapperBuilder
(
volName
string
,
spec
Spec
,
pod
*
api
.
Pod
,
opts
VolumeOptions
)
(
Builder
,
error
)
// NewWrapperCleaner finds an appropriate plugin with which to handle
// the provided spec. See comments on NewWrapperBuilder for more
// context.
NewWrapperCleaner
(
spec
*
Spec
,
podUID
types
.
UID
)
(
Cleaner
,
error
)
NewWrapperCleaner
(
volName
string
,
spec
Spec
,
podUID
types
.
UID
)
(
Cleaner
,
error
)
// Get cloud provider from kubelet.
GetCloudProvider
()
cloudprovider
.
Interface
...
...
pkg/volume/secret/secret.go
View file @
52cb4c1d
...
...
@@ -47,6 +47,10 @@ type secretPlugin struct {
var
_
volume
.
VolumePlugin
=
&
secretPlugin
{}
var
wrappedVolumeSpec
=
volume
.
Spec
{
Volume
:
&
api
.
Volume
{
VolumeSource
:
api
.
VolumeSource
{
EmptyDir
:
&
api
.
EmptyDirVolumeSource
{
Medium
:
api
.
StorageMediumMemory
}}},
}
func
(
plugin
*
secretPlugin
)
Init
(
host
volume
.
VolumeHost
)
error
{
plugin
.
host
=
host
return
nil
...
...
@@ -62,14 +66,31 @@ func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool {
func
(
plugin
*
secretPlugin
)
NewBuilder
(
spec
*
volume
.
Spec
,
pod
*
api
.
Pod
,
opts
volume
.
VolumeOptions
)
(
volume
.
Builder
,
error
)
{
return
&
secretVolumeBuilder
{
secretVolume
:
&
secretVolume
{
spec
.
Name
(),
pod
.
UID
,
plugin
,
plugin
.
host
.
GetMounter
(),
plugin
.
host
.
GetWriter
(),
volume
.
MetricsNil
{}},
secretName
:
spec
.
Volume
.
Secret
.
SecretName
,
pod
:
*
pod
,
opts
:
&
opts
},
nil
secretVolume
:
&
secretVolume
{
spec
.
Name
(),
pod
.
UID
,
plugin
,
plugin
.
host
.
GetMounter
(),
plugin
.
host
.
GetWriter
(),
volume
.
MetricsNil
{},
},
secretName
:
spec
.
Volume
.
Secret
.
SecretName
,
pod
:
*
pod
,
opts
:
&
opts
,
},
nil
}
func
(
plugin
*
secretPlugin
)
NewCleaner
(
volName
string
,
podUID
types
.
UID
)
(
volume
.
Cleaner
,
error
)
{
return
&
secretVolumeCleaner
{
&
secretVolume
{
volName
,
podUID
,
plugin
,
plugin
.
host
.
GetMounter
(),
plugin
.
host
.
GetWriter
(),
volume
.
MetricsNil
{}}},
nil
return
&
secretVolumeCleaner
{
&
secretVolume
{
volName
,
podUID
,
plugin
,
plugin
.
host
.
GetMounter
(),
plugin
.
host
.
GetWriter
(),
volume
.
MetricsNil
{},
},
},
nil
}
type
secretVolume
struct
{
...
...
@@ -111,11 +132,6 @@ func (b *secretVolumeBuilder) SetUp() error {
return
b
.
SetUpAt
(
b
.
GetPath
())
}
// This is the spec for the volume that this plugin wraps.
var
wrappedVolumeSpec
=
&
volume
.
Spec
{
Volume
:
&
api
.
Volume
{
VolumeSource
:
api
.
VolumeSource
{
EmptyDir
:
&
api
.
EmptyDirVolumeSource
{
Medium
:
api
.
StorageMediumMemory
}}},
}
func
(
b
*
secretVolumeBuilder
)
getMetaDir
()
string
{
return
path
.
Join
(
b
.
plugin
.
host
.
GetPodPluginDir
(
b
.
podUID
,
strings
.
EscapeQualifiedNameForDisk
(
secretPluginName
)),
b
.
volName
)
}
...
...
@@ -137,7 +153,7 @@ func (b *secretVolumeBuilder) SetUpAt(dir string) error {
glog
.
V
(
3
)
.
Infof
(
"Setting up volume %v for pod %v at %v"
,
b
.
volName
,
b
.
pod
.
UID
,
dir
)
// Wrap EmptyDir, let it do the setup.
wrapped
,
err
:=
b
.
plugin
.
host
.
NewWrapperBuilder
(
wrappedVolumeSpec
,
&
b
.
pod
,
*
b
.
opts
)
wrapped
,
err
:=
b
.
plugin
.
host
.
NewWrapperBuilder
(
b
.
volName
,
wrappedVolumeSpec
,
&
b
.
pod
,
*
b
.
opts
)
if
err
!=
nil
{
return
err
}
...
...
@@ -202,7 +218,7 @@ func (c *secretVolumeCleaner) TearDownAt(dir string) error {
glog
.
V
(
3
)
.
Infof
(
"Tearing down volume %v for pod %v at %v"
,
c
.
volName
,
c
.
podUID
,
dir
)
// Wrap EmptyDir, let it do the teardown.
wrapped
,
err
:=
c
.
plugin
.
host
.
NewWrapperCleaner
(
wrappedVolumeSpec
,
c
.
podUID
)
wrapped
,
err
:=
c
.
plugin
.
host
.
NewWrapperCleaner
(
c
.
volName
,
wrappedVolumeSpec
,
c
.
podUID
)
if
err
!=
nil
{
return
err
}
...
...
pkg/volume/secret/secret_test.go
View file @
52cb4c1d
...
...
@@ -70,11 +70,11 @@ func TestPlugin(t *testing.T) {
testNamespace
=
"test_secret_namespace"
testName
=
"test_secret_name"
volumeSpec
=
volumeSpec
(
testVolumeName
,
testName
)
secret
=
secret
(
testNamespace
,
testName
)
client
=
testclient
.
NewSimpleFake
(
&
secret
)
pluginMgr
=
volume
.
VolumePluginMgr
{}
_
,
host
=
newTestHost
(
t
,
client
)
volumeSpec
=
volumeSpec
(
testVolumeName
,
testName
)
secret
=
secret
(
testNamespace
,
testName
)
client
=
testclient
.
NewSimpleFake
(
&
secret
)
pluginMgr
=
volume
.
VolumePluginMgr
{}
rootDir
,
host
=
newTestHost
(
t
,
client
)
)
pluginMgr
.
InitPlugins
(
ProbeVolumePlugins
(),
host
)
...
...
@@ -110,6 +110,16 @@ func TestPlugin(t *testing.T) {
}
}
// secret volume should create its own empty wrapper path
podWrapperMetadataDir
:=
fmt
.
Sprintf
(
"%v/pods/test_pod_uid/plugins/kubernetes.io~empty-dir/wrapped_test_volume_name"
,
rootDir
)
if
_
,
err
:=
os
.
Stat
(
podWrapperMetadataDir
);
err
!=
nil
{
if
os
.
IsNotExist
(
err
)
{
t
.
Errorf
(
"SetUp() failed, empty-dir wrapper path is not created: %s"
,
podWrapperMetadataDir
)
}
else
{
t
.
Errorf
(
"SetUp() failed: %v"
,
err
)
}
}
doTestSecretDataInVolume
(
volumePath
,
secret
,
t
)
doTestCleanAndTeardown
(
plugin
,
testPodUID
,
testVolumeName
,
volumePath
,
t
)
}
...
...
pkg/volume/testing.go
View file @
52cb4c1d
...
...
@@ -81,16 +81,26 @@ func (f *fakeVolumeHost) GetWriter() io.Writer {
return
f
.
writer
}
func
(
f
*
fakeVolumeHost
)
NewWrapperBuilder
(
spec
*
Spec
,
pod
*
api
.
Pod
,
opts
VolumeOptions
)
(
Builder
,
error
)
{
plug
,
err
:=
f
.
pluginMgr
.
FindPluginBySpec
(
spec
)
func
(
f
*
fakeVolumeHost
)
NewWrapperBuilder
(
volName
string
,
spec
Spec
,
pod
*
api
.
Pod
,
opts
VolumeOptions
)
(
Builder
,
error
)
{
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName
:=
"wrapped_"
+
volName
if
spec
.
Volume
!=
nil
{
spec
.
Volume
.
Name
=
wrapperVolumeName
}
plug
,
err
:=
f
.
pluginMgr
.
FindPluginBySpec
(
&
spec
)
if
err
!=
nil
{
return
nil
,
err
}
return
plug
.
NewBuilder
(
spec
,
pod
,
opts
)
return
plug
.
NewBuilder
(
&
spec
,
pod
,
opts
)
}
func
(
f
*
fakeVolumeHost
)
NewWrapperCleaner
(
spec
*
Spec
,
podUID
types
.
UID
)
(
Cleaner
,
error
)
{
plug
,
err
:=
f
.
pluginMgr
.
FindPluginBySpec
(
spec
)
func
(
f
*
fakeVolumeHost
)
NewWrapperCleaner
(
volName
string
,
spec
Spec
,
podUID
types
.
UID
)
(
Cleaner
,
error
)
{
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName
:=
"wrapped_"
+
volName
if
spec
.
Volume
!=
nil
{
spec
.
Volume
.
Name
=
wrapperVolumeName
}
plug
,
err
:=
f
.
pluginMgr
.
FindPluginBySpec
(
&
spec
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
test/e2e/empty_dir_wrapper.go
0 → 100644
View file @
52cb4c1d
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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
e2e
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/intstr"
"strconv"
.
"github.com/onsi/ginkgo"
)
// This test will create a pod with a secret volume and gitRepo volume
// Thus requests a secret, a git server pod, and a git server service
var
_
=
Describe
(
"EmptyDir wrapper volumes"
,
func
()
{
f
:=
NewFramework
(
"secrets"
)
It
(
"should becomes running [Conformance]"
,
func
()
{
name
:=
"secret-test-"
+
string
(
util
.
NewUUID
())
volumeName
:=
"secret-volume"
volumeMountPath
:=
"/etc/secret-volume"
secret
:=
&
api
.
Secret
{
ObjectMeta
:
api
.
ObjectMeta
{
Namespace
:
f
.
Namespace
.
Name
,
Name
:
name
,
},
Data
:
map
[
string
][]
byte
{
"data-1"
:
[]
byte
(
"value-1
\n
"
),
},
}
var
err
error
if
secret
,
err
=
f
.
Client
.
Secrets
(
f
.
Namespace
.
Name
)
.
Create
(
secret
);
err
!=
nil
{
Failf
(
"unable to create test secret %s: %v"
,
secret
.
Name
,
err
)
}
gitServerPodName
:=
"git-server-"
+
string
(
util
.
NewUUID
())
containerPort
:=
8000
labels
:=
map
[
string
]
string
{
"name"
:
gitServerPodName
}
gitServerPod
:=
&
api
.
Pod
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
gitServerPodName
,
Labels
:
labels
,
},
Spec
:
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{
{
Name
:
"git-repo"
,
Image
:
"gcr.io/google_containers/fakegitserver:0.1"
,
ImagePullPolicy
:
"IfNotPresent"
,
Ports
:
[]
api
.
ContainerPort
{
{
ContainerPort
:
containerPort
},
},
},
},
},
}
if
gitServerPod
,
err
=
f
.
Client
.
Pods
(
f
.
Namespace
.
Name
)
.
Create
(
gitServerPod
);
err
!=
nil
{
Failf
(
"unable to create test git server pod %s: %v"
,
gitServerPod
.
Name
,
err
)
}
// Portal IP and port
httpPort
:=
2345
gitServerSvc
:=
&
api
.
Service
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"git-server-svc"
,
},
Spec
:
api
.
ServiceSpec
{
Selector
:
labels
,
Ports
:
[]
api
.
ServicePort
{
{
Name
:
"http-portal"
,
Port
:
httpPort
,
TargetPort
:
intstr
.
FromInt
(
containerPort
),
},
},
},
}
if
gitServerSvc
,
err
=
f
.
Client
.
Services
(
f
.
Namespace
.
Name
)
.
Create
(
gitServerSvc
);
err
!=
nil
{
Failf
(
"unable to create test git server service %s: %v"
,
gitServerSvc
.
Name
,
err
)
}
gitVolumeName
:=
"git-volume"
gitVolumeMountPath
:=
"/etc/git-volume"
gitURL
:=
"http://"
+
gitServerSvc
.
Spec
.
ClusterIP
+
":"
+
strconv
.
Itoa
(
httpPort
)
gitRepo
:=
"test"
pod
:=
&
api
.
Pod
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"pod-secrets-"
+
string
(
util
.
NewUUID
()),
},
Spec
:
api
.
PodSpec
{
Volumes
:
[]
api
.
Volume
{
{
Name
:
volumeName
,
VolumeSource
:
api
.
VolumeSource
{
Secret
:
&
api
.
SecretVolumeSource
{
SecretName
:
name
,
},
},
},
{
Name
:
gitVolumeName
,
VolumeSource
:
api
.
VolumeSource
{
GitRepo
:
&
api
.
GitRepoVolumeSource
{
Repository
:
gitURL
,
Directory
:
gitRepo
,
},
},
},
},
Containers
:
[]
api
.
Container
{
{
Name
:
"secret-test"
,
Image
:
"gcr.io/google_containers/test-webserver"
,
VolumeMounts
:
[]
api
.
VolumeMount
{
{
Name
:
volumeName
,
MountPath
:
volumeMountPath
,
ReadOnly
:
true
,
},
{
Name
:
gitVolumeName
,
MountPath
:
gitVolumeMountPath
,
},
},
},
},
},
}
if
pod
,
err
=
f
.
Client
.
Pods
(
f
.
Namespace
.
Name
)
.
Create
(
pod
);
err
!=
nil
{
Failf
(
"unable to create pod %v: %v"
,
pod
.
Name
,
err
)
}
defer
func
()
{
By
(
"Cleaning up the secret"
)
if
err
:=
f
.
Client
.
Secrets
(
f
.
Namespace
.
Name
)
.
Delete
(
secret
.
Name
);
err
!=
nil
{
Failf
(
"unable to delete secret %v: %v"
,
secret
.
Name
,
err
)
}
By
(
"Cleaning up the git server pod"
)
if
err
=
f
.
Client
.
Pods
(
f
.
Namespace
.
Name
)
.
Delete
(
gitServerPod
.
Name
,
api
.
NewDeleteOptions
(
0
));
err
!=
nil
{
Failf
(
"unable to delete git server pod %v: %v"
,
gitServerPod
.
Name
,
err
)
}
By
(
"Cleaning up the git server svc"
)
if
err
=
f
.
Client
.
Services
(
f
.
Namespace
.
Name
)
.
Delete
(
gitServerSvc
.
Name
);
err
!=
nil
{
Failf
(
"unable to delete git server svc %v: %v"
,
gitServerSvc
.
Name
,
err
)
}
By
(
"Cleaning up the git vol pod"
)
if
err
=
f
.
Client
.
Pods
(
f
.
Namespace
.
Name
)
.
Delete
(
pod
.
Name
,
api
.
NewDeleteOptions
(
0
));
err
!=
nil
{
Failf
(
"unable to delete git vol pod %v: %v"
,
pod
.
Name
,
err
)
}
}()
expectNoError
(
waitForPodRunningInNamespace
(
f
.
Client
,
pod
.
Name
,
f
.
Namespace
.
Name
))
})
})
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