Merge pull request #15519 from msharran/issue/15338

`minikube cp` now supports providing directory as a target
pull/16886/head
Steven Powell 2023-07-14 10:10:04 -07:00 committed by GitHub
commit 08216d673c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 2 deletions

View File

@ -17,6 +17,8 @@ limitations under the License.
package cmd package cmd
import ( import (
"path/filepath"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -56,8 +58,10 @@ Example Command : "minikube cp a.txt /home/docker/b.txt" +
minikube cp <source file path> <target file absolute path> (example: "minikube cp a/b.txt /copied.txt")`) minikube cp <source file path> <target file absolute path> (example: "minikube cp a/b.txt /copied.txt")`)
} }
src := newRemotePath(args[0]) srcPath := args[0]
dst := newRemotePath(args[1]) dstPath := setDstFileNameFromSrc(args[1], srcPath)
src := newRemotePath(srcPath)
dst := newRemotePath(dstPath)
validateArgs(src, dst) validateArgs(src, dst)
co := mustload.Running(ClusterFlagValue()) co := mustload.Running(ClusterFlagValue())
@ -83,6 +87,54 @@ Example Command : "minikube cp a.txt /home/docker/b.txt" +
func init() { func init() {
} }
// setDstFileNameFromSrc sets the src filename as dst filename
// when the dst file name is not provided and ends with a `/`.
// Otherwise this function is a no-op and returns the passed dst.
func setDstFileNameFromSrc(dst, src string) string {
srcPath := newRemotePath(src)
dstPath := newRemotePath(dst)
guestToHost := srcPath.node != "" && dstPath.node == ""
guestToGuest := srcPath.node != "" && dstPath.node != ""
// Since Host can be any OS and Guest can only be linux, use
// filepath and path respectively
var dd, df, sf string
switch {
case guestToHost:
_, sf = pt.Split(src)
dd, df = filepath.Split(dst)
case guestToGuest:
_, sf = pt.Split(src)
dd, df = pt.Split(dst)
default:
_, sf = filepath.Split(src)
dd, df = pt.Split(dst)
}
// if dst is empty, dd and df will be empty, so return dst
// validation will be happening in `validateArgs`
if dd == "" && df == "" {
return ""
}
// if filename is already provided, return dst
if df != "" {
return dst
}
// if src filename is empty, return dst
if sf == "" {
return dst
}
// https://github.com/kubernetes/minikube/pull/15519/files#r1261750910
if guestToHost {
return filepath.Join(dd, sf)
}
return pt.Join(dd, sf)
}
// split path to node name and file path // split path to node name and file path
func newRemotePath(path string) *remotePath { func newRemotePath(path string) *remotePath {
// if destination path is not a absolute path, trying to parse with <node>:<abs path> format // if destination path is not a absolute path, trying to parse with <node>:<abs path> format

View File

@ -60,3 +60,26 @@ func TestParsePath(t *testing.T) {
} }
} }
} }
func TestSetDstFileNameFromSrc(t *testing.T) {
cases := []struct {
src string
dst string
want string
}{
{"./a/b", "/c/", "/c/b"},
{"./a/b", "node:/c/", "node:/c/b"},
{"./a", "/c/", "/c/a"},
{"", "/c/", "/c/"},
{"./a/b", "", ""},
{"./a/b", "/c", "/c"},
{"./a/", "/c/", "/c/"},
}
for _, c := range cases {
got := setDstFileNameFromSrc(c.dst, c.src)
if c.want != got {
t.Fatalf("wrong dst path for src=%s & dst=%s. want: %q, got: %q", c.src, c.dst, c.want, got)
}
}
}