Merge pull request #72641 from dixudx/cp_file_wildcard

kubectl supports copying files with wild card
pull/564/head
Kubernetes Prow Robot 2019-01-24 10:37:15 -08:00 committed by GitHub
commit 9ecce4fdcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 103 additions and 104 deletions

View File

@ -338,65 +338,71 @@ func makeTar(srcPath, destPath string, writer io.Writer) error {
} }
func recursiveTar(srcBase, srcFile, destBase, destFile string, tw *tar.Writer) error { func recursiveTar(srcBase, srcFile, destBase, destFile string, tw *tar.Writer) error {
filepath := path.Join(srcBase, srcFile) srcPath := path.Join(srcBase, srcFile)
stat, err := os.Lstat(filepath) matchedPaths, err := filepath.Glob(srcPath)
if err != nil { if err != nil {
return err return err
} }
if stat.IsDir() { for _, fpath := range matchedPaths {
files, err := ioutil.ReadDir(filepath) stat, err := os.Lstat(fpath)
if err != nil { if err != nil {
return err return err
} }
if len(files) == 0 { if stat.IsDir() {
//case empty directory files, err := ioutil.ReadDir(fpath)
hdr, _ := tar.FileInfoHeader(stat, filepath) if err != nil {
return err
}
if len(files) == 0 {
//case empty directory
hdr, _ := tar.FileInfoHeader(stat, fpath)
hdr.Name = destFile
if err := tw.WriteHeader(hdr); err != nil {
return err
}
}
for _, f := range files {
if err := recursiveTar(srcBase, path.Join(srcFile, f.Name()), destBase, path.Join(destFile, f.Name()), tw); err != nil {
return err
}
}
return nil
} else if stat.Mode()&os.ModeSymlink != 0 {
//case soft link
hdr, _ := tar.FileInfoHeader(stat, fpath)
target, err := os.Readlink(fpath)
if err != nil {
return err
}
hdr.Linkname = target
hdr.Name = destFile hdr.Name = destFile
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err
} }
} } else {
for _, f := range files { //case regular file or other file type like pipe
if err := recursiveTar(srcBase, path.Join(srcFile, f.Name()), destBase, path.Join(destFile, f.Name()), tw); err != nil { hdr, err := tar.FileInfoHeader(stat, fpath)
if err != nil {
return err return err
} }
} hdr.Name = destFile
return nil
} else if stat.Mode()&os.ModeSymlink != 0 {
//case soft link
hdr, _ := tar.FileInfoHeader(stat, filepath)
target, err := os.Readlink(filepath)
if err != nil {
return err
}
hdr.Linkname = target if err := tw.WriteHeader(hdr); err != nil {
hdr.Name = destFile return err
if err := tw.WriteHeader(hdr); err != nil { }
return err
}
} else {
//case regular file or other file type like pipe
hdr, err := tar.FileInfoHeader(stat, filepath)
if err != nil {
return err
}
hdr.Name = destFile
if err := tw.WriteHeader(hdr); err != nil { f, err := os.Open(fpath)
return err if err != nil {
} return err
}
defer f.Close()
f, err := os.Open(filepath) if _, err := io.Copy(tw, f); err != nil {
if err != nil { return err
return err }
return f.Close()
} }
defer f.Close()
if _, err := io.Copy(tw, f); err != nil {
return err
}
return f.Close()
} }
return nil return nil
} }

View File

@ -46,6 +46,7 @@ type FileType int
const ( const (
RegularFile FileType = 0 RegularFile FileType = 0
SymLink FileType = 1 SymLink FileType = 1
RegexFile FileType = 2
) )
func TestExtractFileSpec(t *testing.T) { func TestExtractFileSpec(t *testing.T) {
@ -209,6 +210,7 @@ func TestTarUntar(t *testing.T) {
files := []struct { files := []struct {
name string name string
nameList []string
data string data string
fileType FileType fileType FileType
}{ }{
@ -237,6 +239,12 @@ func TestTarUntar(t *testing.T) {
data: "/tmp/gakki", data: "/tmp/gakki",
fileType: SymLink, fileType: SymLink,
}, },
{
name: "blah*",
nameList: []string{"blah1", "blah2"},
data: "regexp file name",
fileType: RegexFile,
},
} }
for _, file := range files { for _, file := range files {
@ -245,26 +253,19 @@ func TestTarUntar(t *testing.T) {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if file.fileType == RegularFile { if file.fileType == RegularFile {
f, err := os.Create(filepath) createTmpFile(t, filepath, file.data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer f.Close()
if _, err := io.Copy(f, bytes.NewBuffer([]byte(file.data))); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err := f.Close(); err != nil {
t.Fatal(err)
}
} else if file.fileType == SymLink { } else if file.fileType == SymLink {
err := os.Symlink(file.data, filepath) err := os.Symlink(file.data, filepath)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
} else if file.fileType == RegexFile {
for _, fileName := range file.nameList {
createTmpFile(t, path.Join(dir, fileName), file.data)
}
} else { } else {
t.Fatalf("unexpected file type: %v", file) t.Fatalf("unexpected file type: %v", file)
} }
} }
writer := &bytes.Buffer{} writer := &bytes.Buffer{}
@ -282,22 +283,7 @@ func TestTarUntar(t *testing.T) {
filePath := filepath.Join(absPath, file.name) filePath := filepath.Join(absPath, file.name)
if file.fileType == RegularFile { if file.fileType == RegularFile {
f, err := os.Open(filePath) cmpFileData(t, filePath, file.data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer f.Close()
buff := &bytes.Buffer{}
if _, err := io.Copy(buff, f); err != nil {
t.Fatal(err)
}
if err := f.Close(); err != nil {
t.Fatal(err)
}
if file.data != string(buff.Bytes()) {
t.Fatalf("expected: %s, saw: %s", file.data, string(buff.Bytes()))
}
} else if file.fileType == SymLink { } else if file.fileType == SymLink {
dest, err := os.Readlink(filePath) dest, err := os.Readlink(filePath)
@ -308,6 +294,10 @@ func TestTarUntar(t *testing.T) {
if file.data != dest { if file.data != dest {
t.Fatalf("expected: %s, saw: %s", file.data, dest) t.Fatalf("expected: %s, saw: %s", file.data, dest)
} }
} else if file.fileType == RegexFile {
for _, fileName := range file.nameList {
cmpFileData(t, path.Join(dir, fileName), file.data)
}
} else { } else {
t.Fatalf("unexpected file type: %v", file) t.Fatalf("unexpected file type: %v", file)
} }
@ -362,17 +352,7 @@ func TestCopyToLocalFileOrDir(t *testing.T) {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
t.FailNow() t.FailNow()
} }
srcFile, err := os.Create(srcFilePath) createTmpFile(t, srcFilePath, file.data)
if err != nil {
t.Errorf("unexpected error: %v", err)
t.FailNow()
}
defer srcFile.Close()
if _, err := io.Copy(srcFile, bytes.NewBuffer([]byte(file.data))); err != nil {
t.Errorf("unexpected error: %v", err)
t.FailNow()
}
if file.destDirExists { if file.destDirExists {
if err := os.MkdirAll(destPath, 0755); err != nil { if err := os.MkdirAll(destPath, 0755); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -400,7 +380,6 @@ func TestCopyToLocalFileOrDir(t *testing.T) {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
t.FailNow() t.FailNow()
} }
actualDestFilePath := destPath actualDestFilePath := destPath
if file.destDirExists { if file.destDirExists {
actualDestFilePath = filepath.Join(destPath, filepath.Base(srcFilePath)) actualDestFilePath = filepath.Join(destPath, filepath.Base(srcFilePath))
@ -409,17 +388,7 @@ func TestCopyToLocalFileOrDir(t *testing.T) {
if err != nil && os.IsNotExist(err) { if err != nil && os.IsNotExist(err) {
t.Errorf("expecting %s exists, but actually it's missing", actualDestFilePath) t.Errorf("expecting %s exists, but actually it's missing", actualDestFilePath)
} }
destFile, err := os.Open(actualDestFilePath) cmpFileData(t, actualDestFilePath, file.data)
if err != nil {
t.Errorf("unexpected error: %v", err)
t.FailNow()
}
defer destFile.Close()
buff := &bytes.Buffer{}
io.Copy(buff, destFile)
if file.data != string(buff.Bytes()) {
t.Errorf("expected: %s, actual: %s", file.data, string(buff.Bytes()))
}
}() }()
} }
@ -470,16 +439,7 @@ func TestTarDestinationName(t *testing.T) {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
t.FailNow() t.FailNow()
} }
f, err := os.Create(filepath) createTmpFile(t, filepath, file.data)
if err != nil {
t.Errorf("unexpected error: %v", err)
t.FailNow()
}
defer f.Close()
if _, err := io.Copy(f, bytes.NewBuffer([]byte(file.data))); err != nil {
t.Errorf("unexpected error: %v", err)
t.FailNow()
}
} }
reader, writer := io.Pipe() reader, writer := io.Pipe()
@ -743,3 +703,36 @@ func TestValidate(t *testing.T) {
}) })
} }
} }
func createTmpFile(t *testing.T, filepath, data string) {
f, err := os.Create(filepath)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer f.Close()
if _, err := io.Copy(f, bytes.NewBuffer([]byte(data))); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err := f.Close(); err != nil {
t.Fatal(err)
}
}
func cmpFileData(t *testing.T, filePath, data string) {
f, err := os.Open(filePath)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer f.Close()
buff := &bytes.Buffer{}
if _, err := io.Copy(buff, f); err != nil {
t.Fatal(err)
}
if err := f.Close(); err != nil {
t.Fatal(err)
}
if data != string(buff.Bytes()) {
t.Fatalf("expected: %s, saw: %s", data, string(buff.Bytes()))
}
}