github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/imagetool/copyFilteredFiles.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "syscall" 9 10 "github.com/Cloud-Foundations/Dominator/lib/filter" 11 "github.com/Cloud-Foundations/Dominator/lib/fsutil" 12 "github.com/Cloud-Foundations/Dominator/lib/log" 13 ) 14 15 func copyFilteredFilesSubcommand(args []string, logger log.DebugLogger) error { 16 if err := copyFilteredFiles(args[0], args[1], args[2], logger); err != nil { 17 return fmt.Errorf("Error copying filtered files: %s", err) 18 } 19 return nil 20 } 21 22 func copyFilteredFiles(imageName, sourceDirectory, destDirectory string, 23 logger log.DebugLogger) error { 24 scanFilter, err := filter.New(scanExcludeList) 25 if err != nil { 26 return err 27 } 28 img, err := getImageMetadata(imageName) 29 if err != nil { 30 return err 31 } 32 sourceRoot, err := ioutil.TempDir("", "") 33 if err != nil { 34 return err 35 } 36 defer os.Remove(sourceRoot) 37 errorChannel := make(chan error) 38 go func() { 39 errorChannel <- copyFilteredRoot(scanFilter, img.Filter, 40 sourceDirectory, sourceRoot, destDirectory, logger) 41 }() 42 return <-errorChannel 43 } 44 45 func copyFilteredRoot(scanFilter, imageFilter *filter.Filter, 46 sourceDirectory, sourceRoot, destDirectory string, 47 logger log.DebugLogger) error { 48 return walkFilteredRoot(scanFilter, imageFilter, sourceDirectory, 49 sourceRoot, 50 func(path string, fi os.FileInfo) error { 51 stat, ok := fi.Sys().(*syscall.Stat_t) 52 if !ok { 53 return fmt.Errorf("bad FileInfo.Sys() type: %T", fi.Sys()) 54 } 55 destpath := filepath.Join(destDirectory, path) 56 srcpath := filepath.Join(sourceDirectory, path) 57 if fi.IsDir() { 58 if err := os.Mkdir(destpath, fi.Mode()); err != nil { 59 if !os.IsExist(err) { 60 return err 61 } 62 } 63 } else if fi.Mode() & ^os.ModePerm != 0 { 64 return nil 65 } else { 66 err := fsutil.CopyFile(destpath, srcpath, fi.Mode()) 67 if err != nil { 68 return err 69 } 70 } 71 if stat.Uid != 0 || stat.Gid != 0 { 72 err := os.Chown(destpath, int(stat.Uid), int(stat.Gid)) 73 if err != nil { 74 return err 75 } 76 } 77 err := os.Chtimes(destpath, fi.ModTime(), fi.ModTime()) 78 if err != nil { 79 return err 80 } 81 return nil 82 }, 83 logger) 84 }