jx/internal/resource/file.go
2024-03-20 09:15:27 -07:00

120 lines
2.3 KiB
Go

package resource
import (
"fmt"
"os"
"os/user"
"io"
"syscall"
"gopkg.in/yaml.v3"
"strconv"
)
func init() {
ResourceTypes.Register("file", func() Resource { return NewFile() })
}
type File struct {
loader YamlLoader
Path string `yaml:"path"`
Owner string `yaml:"owner"`
Group string `yaml:"group"`
Mode string `yaml:"mode"`
Content string `yaml:"content"`
State string `yaml:"state"`
}
func NewFile() *File {
return &File{ loader: YamlLoadDecl }
}
func (f *File) Apply() error {
switch f.State {
case "absent":
removeErr := os.Remove(f.Path)
if removeErr != nil {
return removeErr
}
case "present": {
uid,uidErr := LookupUID(f.Owner)
if uidErr != nil {
return uidErr
}
gid,gidErr := LookupGID(f.Group)
if gidErr != nil {
return gidErr
}
//e := os.Stat(f.path)
//if os.IsNotExist(e) {
createdFile,e := os.Create(f.Path)
if e != nil {
return e
}
defer createdFile.Close()
if chownErr := createdFile.Chown(uid, gid); chownErr != nil {
return chownErr
}
mode,modeErr := strconv.ParseInt(f.Mode, 8, 64)
if modeErr != nil {
return modeErr
}
if chmodErr := createdFile.Chmod(os.FileMode(mode)); chmodErr != nil {
return chmodErr
}
_,writeErr := createdFile.Write([]byte(f.Content))
if writeErr != nil {
return writeErr
}
}
}
return nil
}
func (f *File) LoadDecl(yamlFileResourceDeclaration string) error {
return f.loader(yamlFileResourceDeclaration, f)
}
func (f *File) Read() ([]byte, error) {
info, e := os.Stat(f.Path)
if e != nil {
panic(e)
}
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
fileUser, userErr := user.LookupId(strconv.Itoa(int(stat.Uid)))
if userErr != nil { //UnknownUserIdError
panic(userErr)
}
fileGroup, groupErr := user.LookupGroupId(strconv.Itoa(int(stat.Gid)))
if groupErr != nil {
panic(groupErr)
}
f.Owner = fileUser.Name
f.Group = fileGroup.Name
}
f.Mode = fmt.Sprintf("%04o", info.Mode().Perm())
file, fileErr := os.Open(f.Path)
if fileErr != nil {
panic(fileErr)
}
fileContent, ioErr := io.ReadAll(file)
if ioErr != nil {
panic(ioErr)
}
f.Content = string(fileContent)
f.State = "present"
return yaml.Marshal(f)
}