// Copyright 2024 Matthew Rich . All rights reserved. package resource import ( "context" "fmt" "gopkg.in/yaml.v3" _ "log" "net/url" _ "os" _ "os/exec" "path/filepath" _ "strings" "io" "gitea.rosskeen.house/rosskeen.house/machine" "decl/internal/codec" ) type Exec struct { stater machine.Stater `yaml:"-" json:"-"` Id string `yaml:"id" json:"id"` CreateTemplate Command `yaml:"create" json:"create"` ReadTemplate Command `yaml:"read" json:"read"` UpdateTemplate Command `yaml:"update" json:"update"` DeleteTemplate Command `yaml:"delete" json:"delete"` config ConfigurationValueGetter // state attributes State string `yaml:"state"` } func init() { ResourceTypes.Register([]string{"exec"}, func(u *url.URL) Resource { x := NewExec() return x }) } func NewExec() *Exec { return &Exec{} } func (x *Exec) Clone() Resource { return &Exec { Id: x.Id, CreateTemplate: x.CreateTemplate, ReadTemplate: x.ReadTemplate, UpdateTemplate: x.UpdateTemplate, DeleteTemplate: x.DeleteTemplate, State: x.State, } } func (x *Exec) StateMachine() machine.Stater { if x.stater == nil { x.stater = ProcessMachine(x) } return x.stater } func (x *Exec) URI() string { return fmt.Sprintf("exec://%s", x.Id) } func (x *Exec) SetURI(uri string) error { resourceUri, e := url.Parse(uri) if e == nil { if resourceUri.Scheme == "exec" { x.Id = filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI()) } else { e = fmt.Errorf("%w: %s is not an exec resource ", ErrInvalidResourceURI, uri) } } return e } func (x *Exec) UseConfig(config ConfigurationValueGetter) { x.config = config } func (x *Exec) ResolveId(ctx context.Context) string { return "" } func (x *Exec) Validate() error { return fmt.Errorf("failed") } func (x *Exec) Apply() error { return nil } func (x *Exec) Notify(m *machine.EventMessage) { ctx := context.Background() switch m.On { case machine.ENTERSTATEEVENT: switch m.Dest { case "start_create": if e := x.Create(ctx); e == nil { if triggerErr := x.stater.Trigger("created"); triggerErr == nil { return } } x.State = "absent" case "present": x.State = "present" } case machine.EXITSTATEEVENT: } } func (x *Exec) Load(r io.Reader) error { return codec.NewYAMLDecoder(r).Decode(x) } func (x *Exec) LoadDecl(yamlResourceDeclaration string) error { return codec.NewYAMLStringDecoder(yamlResourceDeclaration).Decode(x) } func (x *Exec) Type() string { return "exec" } func (x *Exec) Create(ctx context.Context) error { return nil } func (x *Exec) Read(ctx context.Context) ([]byte, error) { return yaml.Marshal(x) }