+
+// copyFile copies a file from src to dst. If dst does not exist, it is created.
+func copyFile(src, dst string) error {
+ sourceFile, err := os.Open(src)
+ if err != nil {
+ return err
+ }
+ defer sourceFile.Close()
+
+ destinationFile, err := os.Create(dst)
+ if err != nil {
+ return err
+ }
+ defer destinationFile.Close()
+
+ _, err = io.Copy(destinationFile, sourceFile)
+ return err
+}
+
+// copyDir recursively copies a directory tree, attempting to preserve permissions.
+func copyDir(src, dst string) error {
+ entries, err := cfgTemplate.ReadDir(src)
+ if err != nil {
+ return err
+ }
+ for _, dirEntry := range entries {
+ if dirEntry.IsDir() {
+ if err := os.MkdirAll(path.Join(dst, dirEntry.Name()), 0777); err != nil {
+ panic(err)
+ }
+ subdirEntries, _ := cfgTemplate.ReadDir(path.Join(src, dirEntry.Name()))
+ for _, subDirEntry := range subdirEntries {
+ f, err := os.Create(path.Join(dst, dirEntry.Name(), subDirEntry.Name()))
+ if err != nil {
+ return err
+ }
+
+ srcFile, err := cfgTemplate.Open(path.Join(src, dirEntry.Name(), subDirEntry.Name()))
+ if err != nil {
+ return fmt.Errorf("error copying srcFile: %w", err)
+ }
+ _, err = io.Copy(f, srcFile)
+ if err != nil {
+ return err
+ }
+ f.Close()
+ }
+ } else {
+ f, err := os.Create(path.Join(dst, dirEntry.Name()))
+ if err != nil {
+ return err
+ }
+
+ srcFile, err := cfgTemplate.Open(path.Join(src, dirEntry.Name()))
+ if err != nil {
+ return err
+ }
+ _, err = io.Copy(f, srcFile)
+ if err != nil {
+ return err
+ }
+ f.Close()
+ }
+ }
+
+ return nil
+}