github.com/gkstretton/dark/services/goo@v0.0.0-20231114224855-2d1a2074d446/filesystem/helpers.go (about) 1 package filesystem 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "os" 8 "os/exec" 9 "time" 10 11 "github.com/gkstretton/dark/services/goo/util/protoyaml" 12 "google.golang.org/protobuf/proto" 13 ) 14 15 func CreateSymlink(original, new string) error { 16 if err := removeSymlink(new); err != nil { 17 return fmt.Errorf("failed to unlink latest: %v", err) 18 } 19 if err := os.Symlink(original, new); err != nil { 20 return fmt.Errorf("failed to symlink latest: %v", err) 21 } 22 SetPerms(new) 23 return nil 24 } 25 26 func removeSymlink(symlinkPath string) error { 27 if _, err := os.Lstat(symlinkPath); err != nil { 28 if errors.Is(err, os.ErrNotExist) { 29 return nil 30 } 31 return fmt.Errorf("failed to stat symlink: %v", err) 32 } 33 if err := os.Remove(symlinkPath); err != nil { 34 return fmt.Errorf("failed to remove symlink: %v", err) 35 } 36 return nil 37 } 38 39 func WriteCreationTimeUsingMetadata(filePath string) error { 40 cmd := exec.Command("./scripts/get-creation-timestamp", filePath) 41 var ts bytes.Buffer 42 cmd.Stdout = &ts 43 if err := cmd.Run(); err != nil { 44 return fmt.Errorf("error getting creation time for %s: %v", filePath, err) 45 } 46 // discard \n 47 ts.Truncate(ts.Len() - 1) 48 49 // fmt.Printf("got creation timestamp %s\n", ts.Bytes()) 50 name := filePath + ".creationtime" 51 if err := os.WriteFile(name, ts.Bytes(), 0666); err != nil { 52 return fmt.Errorf("error writing creation time for %s: %v", filePath, err) 53 } 54 SetPerms(name) 55 return nil 56 } 57 58 func WriteCreationTimeUsingNow(filePath string) error { 59 now := time.Now() 60 ts := fmt.Sprintf("%d.%d", now.Unix(), now.Nanosecond()) 61 62 name := filePath + ".creationtime" 63 if err := os.WriteFile(name, []byte(ts), 0666); err != nil { 64 return fmt.Errorf("error writing creation time for %s: %v", filePath, err) 65 } 66 SetPerms(name) 67 return nil 68 } 69 70 func SetPerms(p string) { 71 // chown to 1000:1000 (host user) 72 cmd := exec.Command("chown", fmt.Sprintf("%d:%d", 1000, 1000), p) 73 out, err := cmd.CombinedOutput() 74 if err != nil { 75 fmt.Printf("chown failed: %v, %s\n", err, string(out)) 76 } 77 } 78 79 func WriteProtoYaml(path string, msg proto.Message) error { 80 data, err := protoyaml.Marshal(msg) 81 if err != nil { 82 return fmt.Errorf("error marshalling delayed dispenses: %v", err) 83 } 84 85 err = os.WriteFile(path, data, 0644) 86 if err != nil { 87 return fmt.Errorf("error writing delayed dispenses file: %v", err) 88 } 89 90 return nil 91 } 92 93 // func chownRecursive(path string, uid, gid int) error { 94 // cmd := exec.Command("chown", "-R", fmt.Sprintf("%d:%d", uid, gid), path) 95 // out, err := cmd.CombinedOutput() 96 // if err != nil { 97 // return fmt.Errorf("chown failed: %v, %s", err, string(out)) 98 // } 99 // return nil 100 // }