Skip to content

Create directory before kubectl cp #1390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 17, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions integration/examples/test-file-sync/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM alpine
COPY . .
CMD while true; do cat /foo && sleep 5; done
1 change: 1 addition & 0 deletions integration/examples/test-file-sync/foo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
foo
8 changes: 8 additions & 0 deletions integration/examples/test-file-sync/pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: Pod
metadata:
name: test-file-sync
spec:
containers:
- name: test-file-sync
image: gcr.io/k8s-skaffold/test-file-sync
14 changes: 14 additions & 0 deletions integration/examples/test-file-sync/skaffold.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: skaffold/v1beta1
kind: Config
build:
tagPolicy:
gitCommit: {}
artifacts:
- image: gcr.io/k8s-skaffold/test-file-sync
context: .
sync:
'**/foo*' : .
deploy:
kubectl:
manifests:
- pod.yaml
59 changes: 57 additions & 2 deletions integration/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,11 @@ func TestDev(t *testing.T) {
dir string
args []string
setup func(t *testing.T) func(t *testing.T)
postSetup func(t *testing.T) func(t *testing.T)
pods []string
jobs []string
jobValidation func(t *testing.T, ns *v1.Namespace, j *batchv1.Job)
validation func(t *testing.T, ns *v1.Namespace)
}

testCases := []testDevCase{
Expand Down Expand Up @@ -268,15 +271,53 @@ func TestDev(t *testing.T) {
}
},
},
{
description: "create a directory with file sync",
dir: "examples/test-file-sync",
args: []string{"dev"},
pods: []string{"test-file-sync"},
postSetup: func(t *testing.T) func(t *testing.T) {
cmd := exec.Command("mkdir", "-p", "test")
cmd.Dir = "examples/test-file-sync"
if output, err := util.RunCmdOut(cmd); err != nil {
t.Fatalf("creating test dir: %s %v", output, err)
}
cmd = exec.Command("touch", "test/foobar")
cmd.Dir = "examples/test-file-sync"
if output, err := util.RunCmdOut(cmd); err != nil {
t.Fatalf("creating test/foo: %s %v", output, err)
}
return func(t *testing.T) {
cmd := exec.Command("rm", "-rf", "test")
cmd.Dir = "examples/test-file-sync"
if output, err := util.RunCmdOut(cmd); err != nil {
t.Fatalf("removing test dir: %s %v", output, err)
}
}
},
validation: func(t *testing.T, ns *v1.Namespace) {
// try to run this command successfully for one minute
err := wait.PollImmediate(time.Millisecond*500, 1*time.Minute, func() (bool, error) {
cmd := exec.Command("kubectl", "exec", "test-file-sync", "-n", ns.Name, "--", "ls", "/test")
_, err := util.RunCmdOut(cmd)
return err == nil, nil
})
if err != nil {
t.Fatalf("checking if /test dir exists in container: %v", err)
}
},
},
}

for _, testCase := range testCases {
t.Run(testCase.description, func(t *testing.T) {
ns, deleteNs := setupNamespace(t)
defer deleteNs()

cleanupTC := testCase.setup(t)
defer cleanupTC(t)
if testCase.setup != nil {
cleanupTC := testCase.setup(t)
defer cleanupTC(t)
}

args := []string{}
args = append(args, testCase.args...)
Expand All @@ -303,6 +344,20 @@ func TestDev(t *testing.T) {
}
}

for _, p := range testCase.pods {
if err := kubernetesutil.WaitForPodReady(context.Background(), client.CoreV1().Pods(ns.Name), p); err != nil {
t.Fatalf("Timed out waiting for pod ready")
}
}

if testCase.postSetup != nil {
cleanup := testCase.postSetup(t)
defer cleanup(t)
}

if testCase.validation != nil {
testCase.validation(t, ns)
}
// No cleanup, since exiting skaffold dev should clean up automatically
})
}
Expand Down
13 changes: 9 additions & 4 deletions pkg/skaffold/sync/kubectl/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"os/exec"
"path/filepath"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/sync"

Expand All @@ -46,10 +47,14 @@ func (k *Syncer) Sync(ctx context.Context, s *sync.Item) error {
return nil
}

func deleteFileFn(ctx context.Context, pod v1.Pod, container v1.Container, src, dst string) *exec.Cmd {
return exec.CommandContext(ctx, "kubectl", "exec", pod.Name, "--namespace", pod.Namespace, "-c", container.Name, "--", "rm", "-rf", dst)
func deleteFileFn(ctx context.Context, pod v1.Pod, container v1.Container, src, dst string) []*exec.Cmd {
delete := exec.CommandContext(ctx, "kubectl", "exec", pod.Name, "--namespace", pod.Namespace, "-c", container.Name, "--", "rm", "-rf", dst)
return []*exec.Cmd{delete}
}

func copyFileFn(ctx context.Context, pod v1.Pod, container v1.Container, src, dst string) *exec.Cmd {
return exec.CommandContext(ctx, "kubectl", "cp", src, fmt.Sprintf("%s/%s:%s", pod.Namespace, pod.Name, dst), "-c", container.Name)
func copyFileFn(ctx context.Context, pod v1.Pod, container v1.Container, src, dst string) []*exec.Cmd {
dir := filepath.Dir(dst)
makeDir := exec.CommandContext(ctx, "kubectl", "exec", pod.Name, "-c", container.Name, "-n", pod.Namespace, "--", "mkdir", "-p", dir)
copy := exec.CommandContext(ctx, "kubectl", "cp", src, fmt.Sprintf("%s/%s:%s", pod.Namespace, pod.Name, dst), "-c", container.Name)
return []*exec.Cmd{makeDir, copy}
}
11 changes: 6 additions & 5 deletions pkg/skaffold/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func intersect(context string, syncMap map[string]string, files []string) (map[s
return ret, nil
}

func Perform(ctx context.Context, image string, files map[string]string, cmdFn func(context.Context, v1.Pod, v1.Container, string, string) *exec.Cmd) error {
func Perform(ctx context.Context, image string, files map[string]string, cmdFn func(context.Context, v1.Pod, v1.Container, string, string) []*exec.Cmd) error {
if len(files) == 0 {
return nil
}
Expand All @@ -154,11 +154,12 @@ func Perform(ctx context.Context, image string, files map[string]string, cmdFn f
}

for src, dst := range files {
cmd := cmdFn(ctx, p, c, src, dst)
if err := util.RunCmd(cmd); err != nil {
return err
cmds := cmdFn(ctx, p, c, src, dst)
for _, cmd := range cmds {
if err := util.RunCmd(cmd); err != nil {
return err
}
}

synced[src] = true
}
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/skaffold/sync/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ func (t *TestCmdRecorder) RunCmdOut(cmd *exec.Cmd) ([]byte, error) {
return nil, t.RunCmd(cmd)
}

func fakeCmd(ctx context.Context, p v1.Pod, c v1.Container, src, dst string) *exec.Cmd {
return exec.CommandContext(ctx, "copy", src, dst)
func fakeCmd(ctx context.Context, p v1.Pod, c v1.Container, src, dst string) []*exec.Cmd {
return []*exec.Cmd{exec.CommandContext(ctx, "copy", src, dst)}
}

var pod = &v1.Pod{
Expand All @@ -371,7 +371,7 @@ func TestPerform(t *testing.T) {
description string
image string
files map[string]string
cmdFn func(context.Context, v1.Pod, v1.Container, string, string) *exec.Cmd
cmdFn func(context.Context, v1.Pod, v1.Container, string, string) []*exec.Cmd
cmdErr error
clientErr error
expected []string
Expand Down