Merge pull request #64747 from soltysh/support_colons

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

kubectl cp support colons-in-filename

**What this PR does / why we need it**:
This is a rebased version of #53127.

/cc @bruceauyeung

**Release note**:
```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue 2018-06-05 04:10:32 -07:00 committed by GitHub
commit 0f9dfca8e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 25 deletions

View File

@ -113,30 +113,25 @@ var (
) )
func extractFileSpec(arg string) (fileSpec, error) { func extractFileSpec(arg string) (fileSpec, error) {
pieces := strings.Split(arg, ":") if i := strings.Index(arg, ":"); i == -1 {
if len(pieces) == 1 {
return fileSpec{File: arg}, nil return fileSpec{File: arg}, nil
} } else if i > 0 {
if len(pieces) != 2 { file := arg[i+1:]
// FIXME Kubernetes can't copy files that contain a ':' pod := arg[:i]
// character. pieces := strings.Split(pod, "/")
return fileSpec{}, errFileSpecDoesntMatchFormat if len(pieces) == 1 {
} return fileSpec{
file := pieces[1] PodName: pieces[0],
File: file,
pieces = strings.Split(pieces[0], "/") }, nil
if len(pieces) == 1 { }
return fileSpec{ if len(pieces) == 2 {
PodName: pieces[0], return fileSpec{
File: file, PodNamespace: pieces[0],
}, nil PodName: pieces[1],
} File: file,
if len(pieces) == 2 { }, nil
return fileSpec{ }
PodNamespace: pieces[0],
PodName: pieces[1],
File: file,
}, nil
} }
return fileSpec{}, errFileSpecDoesntMatchFormat return fileSpec{}, errFileSpecDoesntMatchFormat
@ -177,13 +172,21 @@ func (o *CopyOptions) Run(args []string) error {
if err != nil { if err != nil {
return err return err
} }
if len(srcSpec.PodName) != 0 && len(destSpec.PodName) != 0 {
if _, err := os.Stat(args[0]); err == nil {
return o.copyToPod(fileSpec{File: args[0]}, destSpec)
}
return fmt.Errorf("src doesn't exist in local filesystem")
}
if len(srcSpec.PodName) != 0 { if len(srcSpec.PodName) != 0 {
return o.copyFromPod(srcSpec, destSpec) return o.copyFromPod(srcSpec, destSpec)
} }
if len(destSpec.PodName) != 0 { if len(destSpec.PodName) != 0 {
return o.copyToPod(srcSpec, destSpec) return o.copyToPod(srcSpec, destSpec)
} }
return fmt.Errorf("One of src or dest must be a remote file specification") return fmt.Errorf("one of src or dest must be a remote file specification")
} }
// checkDestinationIsDir receives a destination fileSpec and // checkDestinationIsDir receives a destination fileSpec and

View File

@ -71,13 +71,18 @@ func TestExtractFileSpec(t *testing.T) {
expectedFile: "/some/file", expectedFile: "/some/file",
}, },
{ {
spec: "some:bad:spec", spec: ":file:not:exist:in:local:filesystem",
expectErr: true, expectErr: true,
}, },
{ {
spec: "namespace/pod/invalid:/some/file", spec: "namespace/pod/invalid:/some/file",
expectErr: true, expectErr: true,
}, },
{
spec: "pod:/some/filenamewith:in",
expectedPod: "pod",
expectedFile: "/some/filenamewith:in",
},
} }
for _, test := range tests { for _, test := range tests {
spec, err := extractFileSpec(test.spec) spec, err := extractFileSpec(test.spec)