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  // }