Add e2e test for wrapper volumes

Use git server in e2e and refactor wrapper builder

Update e2e test to use a fake git server
This commit is contained in:
harry 2015-12-14 15:32:37 +08:00 committed by Harry Zhang
parent c0d49450e4
commit 0fa5b6c4f7
15 changed files with 263 additions and 163 deletions

View File

@ -55,10 +55,7 @@ import (
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/empty_dir"
"k8s.io/kubernetes/pkg/volume/git_repo"
"k8s.io/kubernetes/pkg/volume/secret"
"k8s.io/kubernetes/plugin/pkg/scheduler"
_ "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider"
"k8s.io/kubernetes/plugin/pkg/scheduler/factory"
@ -214,7 +211,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
10250, /* KubeletPort */
0, /* ReadOnlyPort */
api.NamespaceDefault,
probeVolumePlugins(),
empty_dir.ProbeVolumePlugins(),
nil,
cadvisorInterface,
configFilePath,
@ -247,7 +244,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
10251, /* KubeletPort */
0, /* ReadOnlyPort */
api.NamespaceDefault,
probeVolumePlugins(),
empty_dir.ProbeVolumePlugins(),
nil,
cadvisorInterface,
"",
@ -268,16 +265,6 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
return apiServer.URL, configFilePath
}
// The list of plugins to probe in this test
func probeVolumePlugins() []volume.VolumePlugin {
allPlugins := []volume.VolumePlugin{}
allPlugins = append(allPlugins, empty_dir.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, git_repo.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, secret.ProbeVolumePlugins()...)
return allPlugins
}
func makeTempDirOrDie(prefix string, baseDir string) string {
if baseDir == "" {
baseDir = "/tmp"
@ -1002,7 +989,6 @@ func main() {
runServiceTest,
runAPIVersionsTest,
runMasterServiceTest,
runWrapperVolumesPluginsTest,
func(c *client.Client) {
runSelfLinkTestOnNamespace(c, api.NamespaceDefault)
runSelfLinkTestOnNamespace(c, "other")
@ -1052,8 +1038,8 @@ func main() {
// 1 pod infra container + 1 container from the service test.
// The total number of container created is 9
if len(createdConts) != 14 {
glog.Fatalf("Expected 14 containers; got %v\n\nlist of created containers:\n\n%#v\n\nDocker 1 Created:\n\n%#v\n\nDocker 2 Created:\n\n%#v\n\n", len(createdConts), createdConts.List(), fakeDocker1.Created, fakeDocker2.Created)
if len(createdConts) != 12 {
glog.Fatalf("Expected 12 containers; got %v\n\nlist of created containers:\n\n%#v\n\nDocker 1 Created:\n\n%#v\n\nDocker 2 Created:\n\n%#v\n\n", len(createdConts), createdConts.List(), fakeDocker1.Created, fakeDocker2.Created)
}
glog.Infof("OK - found created containers: %#v", createdConts.List())
@ -1111,72 +1097,3 @@ const (
}
}`
)
// This is a test to make sure multiple empty_dir wrapper based volumes should not affect each other
func runWrapperVolumesPluginsTest(client *client.Client) {
// Make a secret object.
ns := api.NamespaceDefault
s := api.Secret{
ObjectMeta: api.ObjectMeta{
Name: "secret-name",
Namespace: ns,
},
Data: map[string][]byte{
"data": []byte("value1\n"),
},
}
if _, err := client.Secrets(s.Namespace).Create(&s); err != nil {
glog.Fatalf("unable to create test secret: %v", err)
}
pod := &api.Pod{
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "vol-container",
Image: "kubernetes/pause",
VolumeMounts: []api.VolumeMount{
{
Name: "vol-secret",
MountPath: "/fake/path-1",
ReadOnly: true,
},
{
Name: "vol-git",
MountPath: "/fake/path-2",
},
},
},
},
Volumes: []api.Volume{
{
Name: "vol-secret",
VolumeSource: api.VolumeSource{
Secret: &api.SecretVolumeSource{
SecretName: "secret-name",
},
},
},
{
Name: "vol-git",
VolumeSource: api.VolumeSource{
GitRepo: &api.GitRepoVolumeSource{
Repository: "https://github.com/kubernetes/kubedash",
},
},
},
},
},
}
pod.ObjectMeta.Name = "wrappedvolumes.foo"
foo, err := client.Pods(api.NamespaceDefault).Create(pod)
if err != nil {
glog.Fatalf("Failed to create pod: %v, %v", pod, err)
}
if err := wait.Poll(time.Second, longTestTimeout, podRunning(client, foo.Namespace, foo.Name)); err != nil {
glog.Fatalf("FAILED: pod never started running %v", err)
}
glog.Info("empty_dir wrapper based volumes doesn't affect each other: test passed.")
}

View File

@ -467,11 +467,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")
}

View File

@ -289,11 +289,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")
}

View File

@ -57,16 +57,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
}

View File

@ -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
@ -70,7 +74,6 @@ func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opt
pod: pod,
podUID: pod.UID,
plugin: plugin,
wrappedVolumeSpec: volume.GetWrappedVolumeSpec(spec.Name(), downwardAPIPluginName),
}
v.fieldReferenceFileNames = make(map[string]string)
for _, fileInfo := range spec.Volume.DownwardAPI.Items {
@ -78,15 +81,17 @@ 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{
return &downwardAPIVolumeCleaner{
&downwardAPIVolume{
volName: volName,
podUID: podUID,
plugin: plugin,
wrappedVolumeSpec: volume.GetWrappedVolumeSpec(volName, downwardAPIPluginName)},
},
}, nil
}
@ -98,7 +103,6 @@ type downwardAPIVolume struct {
podUID types.UID // TODO: remove this redundancy as soon NewCleaner func will have *api.POD and not only types.UID
plugin *downwardAPIPlugin
volume.MetricsNil
wrappedVolumeSpec *volume.Spec
}
// downwardAPIVolumeBuilder fetches info from downward API from the pod
@ -132,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(b.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
@ -366,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(c.wrappedVolumeSpec, c.podUID)
wrapped, err := c.plugin.host.NewWrapperCleaner(c.volName, wrappedVolumeSpec, c.podUID)
if err != nil {
return err
}

View File

@ -143,7 +143,7 @@ func TestLabels(t *testing.T) {
t.Errorf("Failed to setup volume: %v", err)
}
// gitRepo volume should create it's own empty wrapper path
// 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 {

View File

@ -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"
)
@ -64,7 +68,6 @@ func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts vo
volName: spec.Name(),
podUID: pod.UID,
plugin: plugin,
wrappedVolumeSpec: volume.GetWrappedVolumeSpec(spec.Name(), gitRepoPluginName),
},
pod: *pod,
source: spec.Volume.GitRepo.Repository,
@ -81,7 +84,6 @@ func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID) (volum
volName: volName,
podUID: podUID,
plugin: plugin,
wrappedVolumeSpec: volume.GetWrappedVolumeSpec(volName, gitRepoPluginName),
},
}, nil
}
@ -92,7 +94,6 @@ type gitRepoVolume struct {
volName string
podUID types.UID
plugin *gitRepoPlugin
wrappedVolumeSpec *volume.Spec
volume.MetricsNil
}
@ -138,7 +139,7 @@ func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error {
}
// Wrap EmptyDir, let it do the setup.
wrapped, err := b.plugin.host.NewWrapperBuilder(b.wrappedVolumeSpec, &b.pod, b.opts)
wrapped, err := b.plugin.host.NewWrapperBuilder(b.volName, wrappedVolumeSpec, &b.pod, b.opts)
if err != nil {
return err
}
@ -218,7 +219,7 @@ func (c *gitRepoVolumeCleaner) TearDown() error {
func (c *gitRepoVolumeCleaner) TearDownAt(dir string) error {
// Wrap EmptyDir, let it do the teardown.
wrapped, err := c.plugin.host.NewWrapperCleaner(c.wrappedVolumeSpec, c.podUID)
wrapped, err := c.plugin.host.NewWrapperCleaner(c.volName, wrappedVolumeSpec, c.podUID)
if err != nil {
return err
}

View File

@ -266,7 +266,7 @@ func doTestPlugin(scenario struct {
}
}
// gitRepo volume should create it's own empty wrapper path
// 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 {

View File

@ -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

View File

@ -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

View File

@ -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
@ -69,7 +73,6 @@ func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts vol
plugin.host.GetMounter(),
plugin.host.GetWriter(),
volume.MetricsNil{},
volume.GetWrappedVolumeSpec(spec.Name(), secretPluginName),
},
secretName: spec.Volume.Secret.SecretName,
pod: *pod,
@ -86,7 +89,6 @@ func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID) (volume
plugin.host.GetMounter(),
plugin.host.GetWriter(),
volume.MetricsNil{},
volume.GetWrappedVolumeSpec(volName, secretPluginName),
},
}, nil
}
@ -98,7 +100,6 @@ type secretVolume struct {
mounter mount.Interface
writer ioutil.Writer
volume.MetricsNil
wrappedVolumeSpec *volume.Spec
}
var _ volume.Volume = &secretVolume{}
@ -152,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(b.wrappedVolumeSpec, &b.pod, *b.opts)
wrapped, err := b.plugin.host.NewWrapperBuilder(b.volName, wrappedVolumeSpec, &b.pod, *b.opts)
if err != nil {
return err
}
@ -217,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(c.wrappedVolumeSpec, c.podUID)
wrapped, err := c.plugin.host.NewWrapperCleaner(c.volName, wrappedVolumeSpec, c.podUID)
if err != nil {
return err
}

View File

@ -110,7 +110,7 @@ func TestPlugin(t *testing.T) {
}
}
// secret volume should create it's own empty wrapper path
// 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 {

View File

@ -80,16 +80,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
}

View File

@ -17,7 +17,6 @@ limitations under the License.
package volume
import (
"fmt"
"io/ioutil"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
@ -25,10 +24,6 @@ import (
"path"
)
const (
randomLength = 5
)
// Volume represents a directory used by pods or hosts on a node.
// All method implementations of methods in the volume interface must be idempotent.
type Volume interface {
@ -137,22 +132,3 @@ func RenameDirectory(oldPath, newName string) (string, error) {
}
return newPath, nil
}
// Return the wrapper volume spec of specific volume plugin
func GetWrappedVolumeSpec(volName string, pluginName string) *Spec {
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName := fmt.Sprintf("wrapped_%v", volName)
var volumeSpec *Spec
switch pluginName {
case "kubernetes.io/downward-api", "kubernetes.io/secret":
volumeSpec = &Spec{
Volume: &api.Volume{Name: wrapperVolumeName, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}}},
}
case "kubernetes.io/git-repo":
volumeSpec = &Spec{
Volume: &api.Volume{Name: wrapperVolumeName, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
}
}
return volumeSpec
}

View File

@ -0,0 +1,179 @@
/*
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))
})
})