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{}