add support for file resource access/mod times
All checks were successful
Declarative Tests / test (push) Successful in 53s
All checks were successful
Declarative Tests / test (push) Successful in 53s
This commit is contained in:
parent
0f82fde55d
commit
ce95306eb1
@ -125,24 +125,6 @@ func (c *Container) LoadDecl(yamlFileResourceDeclaration string) error {
|
||||
return c.loader(yamlFileResourceDeclaration, c)
|
||||
}
|
||||
|
||||
/*
|
||||
apiClient, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer apiClient.Close()
|
||||
|
||||
containers, err := apiClient.ContainerList(context.Background(), container.ListOptions{All: true})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, ctr := range containers {
|
||||
fmt.Printf("%s %s (status: %s)\n", ctr.ID, ctr.Image, ctr.Status)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func (c *Container) Create(ctx context.Context) error {
|
||||
numberOfEnvironmentVariables := len(c.Environment)
|
||||
config := &container.Config {
|
||||
|
@ -1,4 +1,6 @@
|
||||
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||
|
||||
//
|
||||
package resource
|
||||
|
||||
import (
|
||||
|
@ -6,7 +6,7 @@ package resource
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
_ "log"
|
||||
"log/slog"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@ -73,11 +73,12 @@ func (d *Declaration) Resource() Resource {
|
||||
}
|
||||
|
||||
func (d *Declaration) SetURI(uri string) error {
|
||||
slog.Info("SetURI()", "uri", uri)
|
||||
d.Implementation = NewResource(uri)
|
||||
if d.Implementation == nil {
|
||||
panic("unknown resource")
|
||||
}
|
||||
d.Type = d.Implementation.Type()
|
||||
d.Implementation.Read(context.Background()) // fix
|
||||
d.Implementation.Read(context.Background()) // fix context
|
||||
return nil
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"time"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func TestNewDocumentLoader(t *testing.T) {
|
||||
@ -71,6 +73,15 @@ func TestDocumentGenerator(t *testing.T) {
|
||||
err := os.WriteFile(file, []byte(fileContent), 0644)
|
||||
assert.Nil(t, err)
|
||||
|
||||
info,statErr := os.Stat(file)
|
||||
assert.Nil(t, statErr)
|
||||
mTime := info.ModTime()
|
||||
stat, ok := info.Sys().(*syscall.Stat_t)
|
||||
assert.True(t, ok)
|
||||
|
||||
aTime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
|
||||
cTime := time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
|
||||
|
||||
expected := fmt.Sprintf(`
|
||||
resources:
|
||||
- type: file
|
||||
@ -81,9 +92,12 @@ resources:
|
||||
mode: "0644"
|
||||
content: |
|
||||
%s
|
||||
atime: %s
|
||||
ctime: %s
|
||||
mtime: %s
|
||||
filetype: "regular"
|
||||
state: present
|
||||
`, file, fileContent)
|
||||
`, file, fileContent, aTime.Format(time.RFC3339Nano), cTime.Format(time.RFC3339Nano), mTime.Format(time.RFC3339Nano))
|
||||
|
||||
var documentYaml strings.Builder
|
||||
d := NewDocument()
|
||||
@ -101,7 +115,7 @@ resources:
|
||||
assert.Equal(t, nil, ey)
|
||||
|
||||
assert.Greater(t, documentYaml.Len(), 0)
|
||||
assert.YAMLEq(t, documentYaml.String(), expected)
|
||||
assert.YAMLEq(t, expected, documentYaml.String())
|
||||
}
|
||||
|
||||
func TestDocumentAddResource(t *testing.T) {
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"strconv"
|
||||
"path/filepath"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileType string
|
||||
@ -46,6 +47,11 @@ type File struct {
|
||||
Owner string `yaml:"owner"`
|
||||
Group string `yaml:"group"`
|
||||
Mode string `yaml:"mode"`
|
||||
|
||||
Atime time.Time `yaml:"atime",omitempty`
|
||||
Ctime time.Time `yaml:"ctime",omitempty`
|
||||
Mtime time.Time `yaml:"mtime",omitempty`
|
||||
|
||||
Content string `yaml:"content",omitempty`
|
||||
FileType FileType `yaml:"filetype"`
|
||||
State string `yaml:"state"`
|
||||
@ -114,6 +120,11 @@ func (f *File) Apply() error {
|
||||
if writeErr != nil {
|
||||
return writeErr
|
||||
}
|
||||
if ! f.Mtime.IsZero() && ! f.Atime.IsZero() {
|
||||
if chtimesErr := os.Chtimes(f.Path, f.Atime, f.Mtime); chtimesErr != nil {
|
||||
return chtimesErr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if chownErr := os.Chown(f.Path, uid, gid); chownErr != nil {
|
||||
@ -152,7 +163,12 @@ func (f *File) Read(ctx context.Context) ([]byte, error) {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
f.Mtime = info.ModTime()
|
||||
|
||||
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
|
||||
f.Atime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
|
||||
f.Ctime = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
|
||||
|
||||
userId := strconv.Itoa(int(stat.Uid))
|
||||
groupId := strconv.Itoa(int(stat.Gid))
|
||||
fileUser, userErr := user.LookupId(userId)
|
||||
|
@ -16,6 +16,8 @@ import (
|
||||
"path/filepath"
|
||||
_ "strings"
|
||||
"testing"
|
||||
"time"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func TestNewFileResource(t *testing.T) {
|
||||
@ -35,17 +37,22 @@ func TestReadFile(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
file, _ := filepath.Abs(filepath.Join(TempDir, "fooread.txt"))
|
||||
|
||||
decl := fmt.Sprintf(`
|
||||
declarationAttributes := `
|
||||
path: "%s"
|
||||
owner: "nobody"
|
||||
group: "nobody"
|
||||
mode: "0600"
|
||||
atime: 2001-12-15T01:01:01.000000001Z
|
||||
ctime: %s
|
||||
mtime: 2001-12-15T01:01:01.000000001Z
|
||||
content: |-
|
||||
test line 1
|
||||
test line 2
|
||||
filetype: "regular"
|
||||
state: present
|
||||
`, file)
|
||||
`
|
||||
|
||||
decl := fmt.Sprintf(declarationAttributes, file, "2001-12-15T01:01:01.000000001Z")
|
||||
|
||||
testFile := NewFile()
|
||||
e := testFile.LoadDecl(decl)
|
||||
@ -59,7 +66,15 @@ func TestReadFile(t *testing.T) {
|
||||
r, e := f.Read(ctx)
|
||||
assert.Equal(t, nil, e)
|
||||
assert.Equal(t, "nobody", f.Owner)
|
||||
assert.YAMLEq(t, decl, string(r))
|
||||
|
||||
info,statErr := os.Stat(file)
|
||||
assert.Nil(t, statErr)
|
||||
stat, ok := info.Sys().(*syscall.Stat_t)
|
||||
assert.True(t, ok)
|
||||
cTime := time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
|
||||
|
||||
expected := fmt.Sprintf(declarationAttributes, file, cTime.Format(time.RFC3339Nano))
|
||||
assert.YAMLEq(t, expected, string(r))
|
||||
}
|
||||
|
||||
func TestCreateFile(t *testing.T) {
|
||||
@ -130,3 +145,25 @@ func TestFileDirectory(t *testing.T) {
|
||||
assert.Nil(t, deleteErr)
|
||||
assert.NoDirExists(t, file)
|
||||
}
|
||||
|
||||
func TestFileTimes(t *testing.T) {
|
||||
file, _ := filepath.Abs(filepath.Join(TempDir, "testtimes.txt"))
|
||||
decl := fmt.Sprintf(`
|
||||
path: "%s"
|
||||
owner: "nobody"
|
||||
group: "nobody"
|
||||
mtime: 2001-12-15T01:01:01.1Z
|
||||
mode: "0600"
|
||||
filtetype: "regular"
|
||||
state: "present"
|
||||
`, file)
|
||||
|
||||
expectedTime, timeErr := time.Parse(time.RFC3339, "2001-12-15T01:01:01.1Z")
|
||||
assert.Nil(t, timeErr)
|
||||
|
||||
f := NewFile()
|
||||
e := f.LoadDecl(decl)
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, "nobody", f.Owner)
|
||||
assert.True(t, f.Mtime.Equal(expectedTime))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user