create instruction with common interface for all available commands + loader (reader.go)
This commit is contained in:
parent
ee73fee310
commit
9f1d2923ba
|
@ -0,0 +1,48 @@
|
||||||
|
package instruction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
// File is the path to the file
|
||||||
|
File string
|
||||||
|
// Path is the configuration field path
|
||||||
|
Path []string
|
||||||
|
// Value if the value to add or update
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *config) Build(_args string) error {
|
||||||
|
|
||||||
|
// 1. extract action (sub command)
|
||||||
|
split := strings.SplitN(_args, " ", 2)
|
||||||
|
|
||||||
|
// 2. check path
|
||||||
|
if len(split) < 2 {
|
||||||
|
return fmt.Errorf("missing configuration path")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. check path separator
|
||||||
|
splitPath := strings.Split(split[0], "@")
|
||||||
|
if len(splitPath) > 2 {
|
||||||
|
return fmt.Errorf("invalid path (additional '@'?)")
|
||||||
|
}
|
||||||
|
|
||||||
|
d.File = splitPath[0]
|
||||||
|
if len(splitPath) > 1 { // add field path only if set
|
||||||
|
d.Path = strings.Split(splitPath[1], ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
// add value
|
||||||
|
d.Value = split[1]
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d config) Exec(ctx ExecutionContext) ([]byte, error) {
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package instruction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.xdrm.io/xdrm-brackets/nix-amer/internal/cnf"
|
||||||
|
"git.xdrm.io/xdrm-brackets/nix-amer/internal/pkg"
|
||||||
|
"git.xdrm.io/xdrm-brackets/nix-amer/internal/ser"
|
||||||
|
)
|
||||||
|
|
||||||
|
// T is the instruction common interface
|
||||||
|
type T interface {
|
||||||
|
// Build the instruction with input arguments
|
||||||
|
Build(string) error
|
||||||
|
// Exec the given instruction
|
||||||
|
Exec(ExecutionContext) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExecutionContext struct {
|
||||||
|
PackageManager pkg.PackageManager
|
||||||
|
Configuration cnf.ConfigurationFormat
|
||||||
|
ServiceManager ser.ServiceManager
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package instruction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type delete struct {
|
||||||
|
Packages []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *delete) Build(_args string) error {
|
||||||
|
d.Packages = strings.Split(_args, " ")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d delete) Exec(ctx ExecutionContext) ([]byte, error) {
|
||||||
|
|
||||||
|
// delete all packages
|
||||||
|
for _, pkg := range d.Packages {
|
||||||
|
|
||||||
|
err := ctx.PackageManager.Remove(pkg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot delete '%s' | %s", pkg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package instruction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrInvalidSyntax = errors.New("invalid instruction format")
|
||||||
|
var ErrUnknownInstruction = errors.New("unknown instruction")
|
|
@ -0,0 +1,31 @@
|
||||||
|
package instruction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type install struct {
|
||||||
|
Packages []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *install) Build(_args string) error {
|
||||||
|
d.Packages = strings.Split(_args, " ")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d install) Exec(ctx ExecutionContext) ([]byte, error) {
|
||||||
|
|
||||||
|
// install all packages
|
||||||
|
for _, pkg := range d.Packages {
|
||||||
|
|
||||||
|
err := ctx.PackageManager.Install(pkg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot install '%s' | %s", pkg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package instruction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parse from a raw line
|
||||||
|
func Parse(raw string) (T, error) {
|
||||||
|
|
||||||
|
// 1. format (trim + split first space)
|
||||||
|
raw = strings.Trim(raw, " \t\n")
|
||||||
|
cmd := strings.SplitN(raw, " ", 2)
|
||||||
|
cmd[0] = strings.Trim(cmd[0], " \t")
|
||||||
|
cmd[1] = strings.Trim(cmd[1], " \t")
|
||||||
|
|
||||||
|
// 2. fail if invalid base syntax 'cmd args...'
|
||||||
|
// where command is 3 letters
|
||||||
|
if len(cmd) < 2 || len(cmd[0]) < 3 || cmd[0][1] == ' ' {
|
||||||
|
return nil, ErrInvalidSyntax
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Extract instruction type
|
||||||
|
switch cmd[0] {
|
||||||
|
case "ins":
|
||||||
|
i := &install{}
|
||||||
|
err := i.Build(cmd[1])
|
||||||
|
return i, err
|
||||||
|
case "del":
|
||||||
|
i := &delete{}
|
||||||
|
err := i.Build(cmd[1])
|
||||||
|
return i, err
|
||||||
|
case "upd":
|
||||||
|
i := &update{}
|
||||||
|
err := i.Build(cmd[1])
|
||||||
|
return i, err
|
||||||
|
case "ser":
|
||||||
|
i := &service{}
|
||||||
|
err := i.Build(cmd[1])
|
||||||
|
return i, err
|
||||||
|
case "cnf":
|
||||||
|
i := &config{}
|
||||||
|
err := i.Build(cmd[1])
|
||||||
|
return i, err
|
||||||
|
default:
|
||||||
|
return nil, ErrUnknownInstruction
|
||||||
|
}
|
||||||
|
|
||||||
|
// return nil, nil
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package instruction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var actions = []string{"enable", "disable", "start", "stop", "reload", "restart"}
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
Action string
|
||||||
|
Services []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *service) Build(_args string) error {
|
||||||
|
|
||||||
|
// 1. extract action (sub command)
|
||||||
|
split := strings.Split(_args, " ")
|
||||||
|
|
||||||
|
// 2. check action
|
||||||
|
if len(split) < 2 {
|
||||||
|
return fmt.Errorf("invalid syntax, missing action or unit")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. fail if unknown action
|
||||||
|
known := false
|
||||||
|
for _, act := range actions {
|
||||||
|
if split[0] == act {
|
||||||
|
known = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !known {
|
||||||
|
return fmt.Errorf("unknown action '%s'", split[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Action = split[0]
|
||||||
|
|
||||||
|
// 4. Store services
|
||||||
|
d.Services = split[1:]
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d service) Exec(ctx ExecutionContext) ([]byte, error) {
|
||||||
|
|
||||||
|
// delete all packages
|
||||||
|
for _, service := range d.Services {
|
||||||
|
|
||||||
|
if err := ctx.ServiceManager.Exec(d.Action, service); err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot %s '%s' | %s", d.Action, service, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package instruction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type update struct{}
|
||||||
|
|
||||||
|
func (d *update) Build(_args string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d update) Exec(ctx ExecutionContext) ([]byte, error) {
|
||||||
|
|
||||||
|
// fetch packages
|
||||||
|
err := ctx.PackageManager.Fetch()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot fetch packages | %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update packages
|
||||||
|
err = ctx.PackageManager.Upgrade()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot upgrade | %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
Loading…
Reference in New Issue