77 lines
1.7 KiB
Go

package openwrt
import (
"bytes"
"context"
"os"
"os/exec"
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/openwrt/uci"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
type UCIController struct {
uciBinPath string
}
// Name implements node.Controller.
func (*UCIController) Name() string {
return "uci-controller"
}
// Reconcile implements node.Controller.
func (c *UCIController) Reconcile(ctx context.Context, state *agent.State) (*agent.State, error) {
uciSpec := spec.NewUCISpec()
if err := state.GetSpec(spec.NameUCI, uciSpec); err != nil {
if errors.Is(err, agent.ErrSpecNotFound) {
logger.Info(ctx, "could not find uci spec, doing nothing")
return state, nil
}
return nil, errors.WithStack(err)
}
c.updateConfiguration(ctx, uciSpec)
return state, nil
}
func (c *UCIController) updateConfiguration(ctx context.Context, spec *spec.UCI) {
logger.Info(ctx, "importing uci config")
if err := c.importConfig(ctx, spec.Config); err != nil {
logger.Error(ctx, "could not import uci config", logger.E(errors.WithStack(err)))
}
}
func (c *UCIController) importConfig(ctx context.Context, uci *uci.UCI) error {
cmd := exec.CommandContext(ctx, c.uciBinPath, "import")
var buf bytes.Buffer
if _, err := buf.WriteString(uci.Export()); err != nil {
return errors.WithStack(err)
}
cmd.Stdin = &buf
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
if err := cmd.Run(); err != nil {
return errors.WithStack(err)
}
return nil
}
func NewUCIController(uciBinPath string) *UCIController {
return &UCIController{uciBinPath}
}
var _ agent.Controller = &UCIController{}