Skip to content

Commit

Permalink
Add Interface to Kanister/kube pkg to support write to a file in pod …
Browse files Browse the repository at this point in the history
…(#5465)

* Add Interface to kube for  write to file in pod

* Address review suggestions

* Nit fix
  • Loading branch information
SupriyaKasten authored and Ilya Kislenko committed Apr 24, 2019
1 parent bdbc0ef commit 0105fd3
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
50 changes: 50 additions & 0 deletions pkg/kube/pod_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package kube

import (
"context"
"io"
"path/filepath"

"github.com/pkg/errors"
"k8s.io/client-go/kubernetes"

"github.com/kanisterio/kanister/pkg/format"
)

// PodWriter specifies Kubernetes Client and the other params needed for writing content to a file
type PodWriter struct {
cli kubernetes.Interface
namespace string
path string
podName string
containerName string
}

// NewPodWriter returns a new PodWriter given Kubernetes Client, Namespace, path of file, name of pod and container
func NewPodWriter(cli kubernetes.Interface, namespace, path, podName, containerName string) *PodWriter {
return &PodWriter{
cli: cli,
namespace: namespace,
path: filepath.Clean(path),
podName: podName,
containerName: containerName,
}
}

// Write will create a new file(if not present) and write the provided content to the file
func (p *PodWriter) Write(ctx context.Context, content io.Reader) error {
cmd := []string{"sh", "-c", "cat - > " + p.path}
stdout, stderr, err := Exec(p.cli, p.namespace, p.podName, p.containerName, cmd, content)
format.Log(p.podName, p.containerName, stdout)
format.Log(p.podName, p.containerName, stderr)
return errors.Wrap(err, "Failed to write contents to file")
}

// Remove will delete the file created by Write() func
func (p *PodWriter) Remove(ctx context.Context) error {
cmd := []string{"sh", "-c", "rm " + p.path}
stdout, stderr, err := Exec(p.cli, p.namespace, p.podName, p.containerName, cmd, nil)
format.Log(p.podName, p.containerName, stdout)
format.Log(p.podName, p.containerName, stderr)
return errors.Wrap(err, "Failed to delete file")
}
79 changes: 79 additions & 0 deletions pkg/kube/pod_writer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// +build !unit

package kube

import (
"bytes"
"context"
"time"

. "gopkg.in/check.v1"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

type PodWriteSuite struct {
cli kubernetes.Interface
namespace string
pod *v1.Pod
}

var _ = Suite(&PodWriteSuite{})

func (p *PodWriteSuite) SetUpSuite(c *C) {
var err error
p.cli, err = NewClient()
c.Assert(err, IsNil)
ns := &v1.Namespace{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "podwritertest-",
},
}
ns, err = p.cli.Core().Namespaces().Create(ns)
c.Assert(err, IsNil)
p.namespace = ns.Name
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "testpod"},
Spec: v1.PodSpec{
Containers: []v1.Container{
v1.Container{
Name: "testcontainer",
Image: "busybox",
Command: []string{"sh", "-c", "tail -f /dev/null"},
},
},
},
}
p.pod, err = p.cli.Core().Pods(p.namespace).Create(pod)
c.Assert(err, IsNil)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
c.Assert(WaitForPodReady(ctx, p.cli, p.namespace, p.pod.Name), IsNil)
p.pod, err = p.cli.Core().Pods(p.namespace).Get(p.pod.Name, metav1.GetOptions{})
c.Assert(err, IsNil)
}

func (p *PodWriteSuite) TearDownSuite(c *C) {
if p.namespace != "" {
err := p.cli.Core().Namespaces().Delete(p.namespace, nil)
c.Assert(err, IsNil)
}
}
func (p *PodWriteSuite) TestPodWriter(c *C) {
path := "/tmp/test.txt"
c.Assert(p.pod.Status.Phase, Equals, v1.PodRunning)
c.Assert(len(p.pod.Status.ContainerStatuses) > 0, Equals, true)
for _, cs := range p.pod.Status.ContainerStatuses {
pw := NewPodWriter(p.cli, p.pod.Namespace, path, p.pod.Name, cs.Name)
err := pw.Write(context.Background(), bytes.NewBufferString("badabing"))
c.Assert(err, IsNil)
cmd := []string{"sh", "-c", "cat " + pw.path}
stdout, stderr, err := Exec(p.cli, p.pod.Namespace, p.pod.Name, cs.Name, cmd, nil)
c.Assert(err, IsNil)
c.Assert(stdout, Equals, "badabing")
c.Assert(stderr, Equals, "")
err = pw.Remove(context.Background())
c.Assert(err, IsNil)
}
}

0 comments on commit 0105fd3

Please sign in to comment.