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  }