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
641b2adc
Unverified
Commit
641b2adc
authored
Feb 04, 2019
by
Kubernetes Prow Robot
Committed by
GitHub
Feb 04, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #73318 from wongma7/subpath-init-write
Do writes in init container before trying reads
parents
2a5a41a0
9f5a7992
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
93 additions
and
28 deletions
+93
-28
subpath.go
test/e2e/storage/testsuites/subpath.go
+93
-28
No files found.
test/e2e/storage/testsuites/subpath.go
View file @
641b2adc
...
@@ -208,8 +208,8 @@ type subPathTestInput struct {
...
@@ -208,8 +208,8 @@ type subPathTestInput struct {
func
testSubPath
(
input
*
subPathTestInput
)
{
func
testSubPath
(
input
*
subPathTestInput
)
{
It
(
"should support non-existent path"
,
func
()
{
It
(
"should support non-existent path"
,
func
()
{
// Write the file in the subPath from
container 0
// Write the file in the subPath from
init container 1
setWriteCommand
(
input
.
filePathInSubpath
,
&
input
.
pod
.
Spec
.
Containers
[
0
])
setWriteCommand
(
input
.
filePathInSubpath
,
&
input
.
pod
.
Spec
.
InitContainers
[
1
])
// Read it from outside the subPath from container 1
// Read it from outside the subPath from container 1
testReadFile
(
input
.
f
,
input
.
filePathInVolume
,
input
.
pod
,
1
)
testReadFile
(
input
.
f
,
input
.
filePathInVolume
,
input
.
pod
,
1
)
...
@@ -219,8 +219,8 @@ func testSubPath(input *subPathTestInput) {
...
@@ -219,8 +219,8 @@ func testSubPath(input *subPathTestInput) {
// Create the directory
// Create the directory
setInitCommand
(
input
.
pod
,
fmt
.
Sprintf
(
"mkdir -p %s"
,
input
.
subPathDir
))
setInitCommand
(
input
.
pod
,
fmt
.
Sprintf
(
"mkdir -p %s"
,
input
.
subPathDir
))
// Write the file in the subPath from
container 0
// Write the file in the subPath from
init container 1
setWriteCommand
(
input
.
filePathInSubpath
,
&
input
.
pod
.
Spec
.
Containers
[
0
])
setWriteCommand
(
input
.
filePathInSubpath
,
&
input
.
pod
.
Spec
.
InitContainers
[
1
])
// Read it from outside the subPath from container 1
// Read it from outside the subPath from container 1
testReadFile
(
input
.
f
,
input
.
filePathInVolume
,
input
.
pod
,
1
)
testReadFile
(
input
.
f
,
input
.
filePathInVolume
,
input
.
pod
,
1
)
...
@@ -291,7 +291,7 @@ func testSubPath(input *subPathTestInput) {
...
@@ -291,7 +291,7 @@ func testSubPath(input *subPathTestInput) {
SubPath
:
"subpath2"
,
SubPath
:
"subpath2"
,
})
})
addMultipleWrites
(
&
input
.
pod
.
Spec
.
Containers
[
0
],
filepath1
,
filepath2
)
addMultipleWrites
(
&
input
.
pod
.
Spec
.
InitContainers
[
1
],
filepath1
,
filepath2
)
testMultipleReads
(
input
.
f
,
input
.
pod
,
0
,
filepath1
,
filepath2
)
testMultipleReads
(
input
.
f
,
input
.
pod
,
0
,
filepath1
,
filepath2
)
})
})
...
@@ -325,8 +325,8 @@ func testSubPath(input *subPathTestInput) {
...
@@ -325,8 +325,8 @@ func testSubPath(input *subPathTestInput) {
// Create the directory
// Create the directory
setInitCommand
(
input
.
pod
,
fmt
.
Sprintf
(
"mkdir -p %s"
,
input
.
subPathDir
))
setInitCommand
(
input
.
pod
,
fmt
.
Sprintf
(
"mkdir -p %s"
,
input
.
subPathDir
))
// Write the file in the volume from
container 1
// Write the file in the volume from
init container 2
setWriteCommand
(
input
.
filePathInVolume
,
&
input
.
pod
.
Spec
.
Containers
[
1
])
setWriteCommand
(
input
.
filePathInVolume
,
&
input
.
pod
.
Spec
.
InitContainers
[
2
])
// Read it from inside the subPath from container 0
// Read it from inside the subPath from container 0
input
.
pod
.
Spec
.
Containers
[
0
]
.
VolumeMounts
[
0
]
.
ReadOnly
=
true
input
.
pod
.
Spec
.
Containers
[
0
]
.
VolumeMounts
[
0
]
.
ReadOnly
=
true
...
@@ -337,8 +337,8 @@ func testSubPath(input *subPathTestInput) {
...
@@ -337,8 +337,8 @@ func testSubPath(input *subPathTestInput) {
// Create the file
// Create the file
setInitCommand
(
input
.
pod
,
fmt
.
Sprintf
(
"touch %s"
,
input
.
subPathDir
))
setInitCommand
(
input
.
pod
,
fmt
.
Sprintf
(
"touch %s"
,
input
.
subPathDir
))
// Write the file in the volume from
container 1
// Write the file in the volume from
init container 2
setWriteCommand
(
input
.
subPathDir
,
&
input
.
pod
.
Spec
.
Containers
[
1
])
setWriteCommand
(
input
.
subPathDir
,
&
input
.
pod
.
Spec
.
InitContainers
[
2
])
// Read it from inside the subPath from container 0
// Read it from inside the subPath from container 0
input
.
pod
.
Spec
.
Containers
[
0
]
.
VolumeMounts
[
0
]
.
ReadOnly
=
true
input
.
pod
.
Spec
.
Containers
[
0
]
.
VolumeMounts
[
0
]
.
ReadOnly
=
true
...
@@ -350,8 +350,19 @@ func testSubPath(input *subPathTestInput) {
...
@@ -350,8 +350,19 @@ func testSubPath(input *subPathTestInput) {
framework
.
Skipf
(
"Volume type %v doesn't support readOnly source"
,
input
.
volType
)
framework
.
Skipf
(
"Volume type %v doesn't support readOnly source"
,
input
.
volType
)
}
}
// Initialize content in the volume while it's writable
pod
:=
input
.
pod
.
DeepCopy
()
initVolumeContent
(
input
.
f
,
input
.
pod
,
input
.
filePathInVolume
,
input
.
filePathInSubpath
)
// Create the directory
setInitCommand
(
input
.
pod
,
fmt
.
Sprintf
(
"mkdir -p %s"
,
input
.
subPathDir
))
// Write the file in the subPath from init container 1
setWriteCommand
(
input
.
filePathInSubpath
,
&
input
.
pod
.
Spec
.
InitContainers
[
1
])
// Read it from inside the subPath from container 0
testReadFile
(
input
.
f
,
input
.
filePathInSubpath
,
input
.
pod
,
0
)
// Reset the pod
input
.
pod
=
pod
// Set volume source to read only
// Set volume source to read only
input
.
pod
.
Spec
.
Volumes
[
0
]
.
VolumeSource
=
*
input
.
roVol
input
.
pod
.
Spec
.
Volumes
[
0
]
.
VolumeSource
=
*
input
.
roVol
...
@@ -384,6 +395,7 @@ func testSubPath(input *subPathTestInput) {
...
@@ -384,6 +395,7 @@ func testSubPath(input *subPathTestInput) {
input
.
pod
.
Spec
.
Containers
[
1
]
.
Command
=
[]
string
{
"/bin/sh"
,
"-ec"
,
"sleep 100000"
}
input
.
pod
.
Spec
.
Containers
[
1
]
.
Command
=
[]
string
{
"/bin/sh"
,
"-ec"
,
"sleep 100000"
}
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
input
.
pod
.
Name
))
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
input
.
pod
.
Name
))
removeUnusedContainers
(
input
.
pod
)
pod
,
err
:=
input
.
f
.
ClientSet
.
CoreV1
()
.
Pods
(
input
.
f
.
Namespace
.
Name
)
.
Create
(
input
.
pod
)
pod
,
err
:=
input
.
f
.
ClientSet
.
CoreV1
()
.
Pods
(
input
.
f
.
Namespace
.
Name
)
.
Create
(
input
.
pod
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while creating pod"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while creating pod"
)
defer
func
()
{
defer
func
()
{
...
@@ -416,6 +428,7 @@ func TestBasicSubpathFile(f *framework.Framework, contents string, pod *v1.Pod,
...
@@ -416,6 +428,7 @@ func TestBasicSubpathFile(f *framework.Framework, contents string, pod *v1.Pod,
setReadCommand
(
filepath
,
&
pod
.
Spec
.
Containers
[
0
])
setReadCommand
(
filepath
,
&
pod
.
Spec
.
Containers
[
0
])
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
removeUnusedContainers
(
pod
)
f
.
TestContainerOutput
(
"atomic-volume-subpath"
,
pod
,
0
,
[]
string
{
contents
})
f
.
TestContainerOutput
(
"atomic-volume-subpath"
,
pod
,
0
,
[]
string
{
contents
})
By
(
fmt
.
Sprintf
(
"Deleting pod %s"
,
pod
.
Name
))
By
(
fmt
.
Sprintf
(
"Deleting pod %s"
,
pod
.
Name
))
...
@@ -467,6 +480,41 @@ func SubpathTestPod(f *framework.Framework, subpath, volumeType string, source *
...
@@ -467,6 +480,41 @@ func SubpathTestPod(f *framework.Framework, subpath, volumeType string, source *
Privileged
:
&
privilegedSecurityContext
,
Privileged
:
&
privilegedSecurityContext
,
},
},
},
},
{
Name
:
fmt
.
Sprintf
(
"test-init-subpath-%s"
,
suffix
),
Image
:
mountImage
,
VolumeMounts
:
[]
v1
.
VolumeMount
{
{
Name
:
volumeName
,
MountPath
:
volumePath
,
SubPath
:
subpath
,
},
{
Name
:
probeVolumeName
,
MountPath
:
probeVolumePath
,
},
},
SecurityContext
:
&
v1
.
SecurityContext
{
Privileged
:
&
privilegedSecurityContext
,
},
},
{
Name
:
fmt
.
Sprintf
(
"test-init-volume-%s"
,
suffix
),
Image
:
mountImage
,
VolumeMounts
:
[]
v1
.
VolumeMount
{
{
Name
:
volumeName
,
MountPath
:
volumePath
,
},
{
Name
:
probeVolumeName
,
MountPath
:
probeVolumePath
,
},
},
SecurityContext
:
&
v1
.
SecurityContext
{
Privileged
:
&
privilegedSecurityContext
,
},
},
},
},
Containers
:
[]
v1
.
Container
{
Containers
:
[]
v1
.
Container
{
{
{
...
@@ -528,6 +576,33 @@ func SubpathTestPod(f *framework.Framework, subpath, volumeType string, source *
...
@@ -528,6 +576,33 @@ func SubpathTestPod(f *framework.Framework, subpath, volumeType string, source *
}
}
}
}
func
containerIsUnused
(
container
*
v1
.
Container
)
bool
{
// mountImage with nil Args does nothing. Leave everything else
return
container
.
Image
==
mountImage
&&
container
.
Args
==
nil
}
// removeUnusedContainers removes containers from a SubpathTestPod that aren't
// needed for a test. e.g. to test for subpath mount failure, only one
// container needs to run and get its status checked.
func
removeUnusedContainers
(
pod
*
v1
.
Pod
)
{
initContainers
:=
[]
v1
.
Container
{}
containers
:=
[]
v1
.
Container
{}
if
pod
.
Spec
.
InitContainers
[
0
]
.
Command
!=
nil
{
initContainers
=
append
(
initContainers
,
pod
.
Spec
.
InitContainers
[
0
])
}
for
_
,
ic
:=
range
pod
.
Spec
.
InitContainers
[
1
:
]
{
if
!
containerIsUnused
(
&
ic
)
{
initContainers
=
append
(
initContainers
,
ic
)
}
}
containers
=
append
(
containers
,
pod
.
Spec
.
Containers
[
0
])
if
!
containerIsUnused
(
&
pod
.
Spec
.
Containers
[
1
])
{
containers
=
append
(
containers
,
pod
.
Spec
.
Containers
[
1
])
}
pod
.
Spec
.
InitContainers
=
initContainers
pod
.
Spec
.
Containers
=
containers
}
// volumeFormatPod returns a Pod that does nothing but will cause the plugin to format a filesystem
// volumeFormatPod returns a Pod that does nothing but will cause the plugin to format a filesystem
// on first use
// on first use
func
volumeFormatPod
(
f
*
framework
.
Framework
,
volumeSource
*
v1
.
VolumeSource
)
*
v1
.
Pod
{
func
volumeFormatPod
(
f
*
framework
.
Framework
,
volumeSource
*
v1
.
VolumeSource
)
*
v1
.
Pod
{
...
@@ -562,6 +637,8 @@ func volumeFormatPod(f *framework.Framework, volumeSource *v1.VolumeSource) *v1.
...
@@ -562,6 +637,8 @@ func volumeFormatPod(f *framework.Framework, volumeSource *v1.VolumeSource) *v1.
func
clearSubpathPodCommands
(
pod
*
v1
.
Pod
)
{
func
clearSubpathPodCommands
(
pod
*
v1
.
Pod
)
{
pod
.
Spec
.
InitContainers
[
0
]
.
Command
=
nil
pod
.
Spec
.
InitContainers
[
0
]
.
Command
=
nil
pod
.
Spec
.
InitContainers
[
1
]
.
Args
=
nil
pod
.
Spec
.
InitContainers
[
2
]
.
Args
=
nil
pod
.
Spec
.
Containers
[
0
]
.
Args
=
nil
pod
.
Spec
.
Containers
[
0
]
.
Args
=
nil
pod
.
Spec
.
Containers
[
1
]
.
Args
=
nil
pod
.
Spec
.
Containers
[
1
]
.
Args
=
nil
}
}
...
@@ -591,6 +668,7 @@ func addMultipleWrites(container *v1.Container, file1 string, file2 string) {
...
@@ -591,6 +668,7 @@ func addMultipleWrites(container *v1.Container, file1 string, file2 string) {
func
testMultipleReads
(
f
*
framework
.
Framework
,
pod
*
v1
.
Pod
,
containerIndex
int
,
file1
string
,
file2
string
)
{
func
testMultipleReads
(
f
*
framework
.
Framework
,
pod
*
v1
.
Pod
,
containerIndex
int
,
file1
string
,
file2
string
)
{
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
removeUnusedContainers
(
pod
)
f
.
TestContainerOutput
(
"multi_subpath"
,
pod
,
containerIndex
,
[]
string
{
f
.
TestContainerOutput
(
"multi_subpath"
,
pod
,
containerIndex
,
[]
string
{
"content of file
\"
"
+
file1
+
"
\"
: mount-tester new file"
,
"content of file
\"
"
+
file1
+
"
\"
: mount-tester new file"
,
"content of file
\"
"
+
file2
+
"
\"
: mount-tester new file"
,
"content of file
\"
"
+
file2
+
"
\"
: mount-tester new file"
,
...
@@ -608,6 +686,7 @@ func testReadFile(f *framework.Framework, file string, pod *v1.Pod, containerInd
...
@@ -608,6 +686,7 @@ func testReadFile(f *framework.Framework, file string, pod *v1.Pod, containerInd
setReadCommand
(
file
,
&
pod
.
Spec
.
Containers
[
containerIndex
])
setReadCommand
(
file
,
&
pod
.
Spec
.
Containers
[
containerIndex
])
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
removeUnusedContainers
(
pod
)
f
.
TestContainerOutput
(
"subpath"
,
pod
,
containerIndex
,
[]
string
{
f
.
TestContainerOutput
(
"subpath"
,
pod
,
containerIndex
,
[]
string
{
"content of file
\"
"
+
file
+
"
\"
: mount-tester new file"
,
"content of file
\"
"
+
file
+
"
\"
: mount-tester new file"
,
})
})
...
@@ -623,6 +702,7 @@ func testPodFailSubpath(f *framework.Framework, pod *v1.Pod, allowContainerTermi
...
@@ -623,6 +702,7 @@ func testPodFailSubpath(f *framework.Framework, pod *v1.Pod, allowContainerTermi
func
testPodFailSubpathError
(
f
*
framework
.
Framework
,
pod
*
v1
.
Pod
,
errorMsg
string
,
allowContainerTerminationError
bool
)
{
func
testPodFailSubpathError
(
f
*
framework
.
Framework
,
pod
*
v1
.
Pod
,
errorMsg
string
,
allowContainerTerminationError
bool
)
{
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
removeUnusedContainers
(
pod
)
pod
,
err
:=
f
.
ClientSet
.
CoreV1
()
.
Pods
(
f
.
Namespace
.
Name
)
.
Create
(
pod
)
pod
,
err
:=
f
.
ClientSet
.
CoreV1
()
.
Pods
(
f
.
Namespace
.
Name
)
.
Create
(
pod
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while creating pod"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while creating pod"
)
defer
func
()
{
defer
func
()
{
...
@@ -704,6 +784,7 @@ func testPodContainerRestart(f *framework.Framework, pod *v1.Pod) {
...
@@ -704,6 +784,7 @@ func testPodContainerRestart(f *framework.Framework, pod *v1.Pod) {
// Start pod
// Start pod
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
removeUnusedContainers
(
pod
)
pod
,
err
:=
f
.
ClientSet
.
CoreV1
()
.
Pods
(
f
.
Namespace
.
Name
)
.
Create
(
pod
)
pod
,
err
:=
f
.
ClientSet
.
CoreV1
()
.
Pods
(
f
.
Namespace
.
Name
)
.
Create
(
pod
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while creating pod"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while creating pod"
)
defer
func
()
{
defer
func
()
{
...
@@ -791,6 +872,7 @@ func testSubpathReconstruction(f *framework.Framework, pod *v1.Pod, forceDelete
...
@@ -791,6 +872,7 @@ func testSubpathReconstruction(f *framework.Framework, pod *v1.Pod, forceDelete
pod
.
Spec
.
TerminationGracePeriodSeconds
=
&
gracePeriod
pod
.
Spec
.
TerminationGracePeriodSeconds
=
&
gracePeriod
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
By
(
fmt
.
Sprintf
(
"Creating pod %s"
,
pod
.
Name
))
removeUnusedContainers
(
pod
)
pod
,
err
:=
f
.
ClientSet
.
CoreV1
()
.
Pods
(
f
.
Namespace
.
Name
)
.
Create
(
pod
)
pod
,
err
:=
f
.
ClientSet
.
CoreV1
()
.
Pods
(
f
.
Namespace
.
Name
)
.
Create
(
pod
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while creating pod"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while creating pod"
)
...
@@ -815,23 +897,6 @@ func formatVolume(f *framework.Framework, pod *v1.Pod) {
...
@@ -815,23 +897,6 @@ func formatVolume(f *framework.Framework, pod *v1.Pod) {
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while deleting volume init pod"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
(),
"while deleting volume init pod"
)
}
}
func
initVolumeContent
(
f
*
framework
.
Framework
,
pod
*
v1
.
Pod
,
volumeFilepath
,
subpathFilepath
string
)
{
setWriteCommand
(
volumeFilepath
,
&
pod
.
Spec
.
Containers
[
1
])
setReadCommand
(
subpathFilepath
,
&
pod
.
Spec
.
Containers
[
0
])
By
(
fmt
.
Sprintf
(
"Creating pod to write volume content %s"
,
pod
.
Name
))
f
.
TestContainerOutput
(
"subpath"
,
pod
,
0
,
[]
string
{
"content of file
\"
"
+
subpathFilepath
+
"
\"
: mount-tester new file"
,
})
By
(
fmt
.
Sprintf
(
"Deleting pod %s"
,
pod
.
Name
))
err
:=
framework
.
DeletePodWithWait
(
f
,
f
.
ClientSet
,
pod
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
(),
"while deleting pod"
)
// This pod spec is going to be reused; reset all the commands
clearSubpathPodCommands
(
pod
)
}
func
podContainerExec
(
pod
*
v1
.
Pod
,
containerIndex
int
,
bashExec
string
)
(
string
,
error
)
{
func
podContainerExec
(
pod
*
v1
.
Pod
,
containerIndex
int
,
bashExec
string
)
(
string
,
error
)
{
return
framework
.
RunKubectl
(
"exec"
,
fmt
.
Sprintf
(
"--namespace=%s"
,
pod
.
Namespace
),
pod
.
Name
,
"--container"
,
pod
.
Spec
.
Containers
[
containerIndex
]
.
Name
,
"--"
,
"/bin/sh"
,
"-c"
,
bashExec
)
return
framework
.
RunKubectl
(
"exec"
,
fmt
.
Sprintf
(
"--namespace=%s"
,
pod
.
Namespace
),
pod
.
Name
,
"--container"
,
pod
.
Spec
.
Containers
[
containerIndex
]
.
Name
,
"--"
,
"/bin/sh"
,
"-c"
,
bashExec
)
}
}
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