Skip to content

Commit

Permalink
feat: dutagent runs module init on startup
Browse files Browse the repository at this point in the history
Signed-off-by: Jens Drenhaus <jens.drenhaus@blindspot.software>
  • Loading branch information
jensdrenhaus committed Sep 26, 2024
1 parent c2a6f40 commit c34757f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
12 changes: 12 additions & 0 deletions cmds/dutagent/dutagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ package main

import (
"context"
"errors"
"log"
"net/http"
"os"

"connectrpc.com/connect"
"github.com/BlindspotSoftware/dutctl/internal/dutagent"
"github.com/BlindspotSoftware/dutctl/protobuf/gen/dutctl/v1/dutctlv1connect"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
Expand Down Expand Up @@ -75,6 +77,16 @@ func main() {
log.Fatal(err)
}

if err = dutagent.Init(cfg.Devices); err != nil {
var initerr *dutagent.ModuleInitError
if errors.As(err, &initerr) {
for mod, err := range initerr.Errs {
log.Printf("init %s failed with:\n%v\n", mod, err)
}
}
log.Fatal(err)
}

agent := &dutagentService{
devices: cfg.Devices,
}
Expand Down
47 changes: 47 additions & 0 deletions internal/dutagent/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package dutagent

import (
"fmt"
"log"

"github.com/BlindspotSoftware/dutctl/pkg/dut"
)

// ModuleInitError is a container for errors that occur during module
// initialization.
type ModuleInitError struct {
Errs map[string]error
}

func (e *ModuleInitError) Error() string {
return fmt.Sprintf("\n%d initialization errors", len(e.Errs))
}

// Init runs the Init function of all modules for all commands of the provided
// devices. All init functions are called, even if an error occurs. In this case
// the an ModuleInitErr is returned that holds all errors reported by the modules.
func Init(devices dut.Devlist) error {
var ierr = &ModuleInitError{
Errs: map[string]error{},
}

for devname, device := range devices {
for cmdname, cmd := range device.Cmds {
for _, module := range cmd.Modules {
err := module.Init()
if err != nil {
m := fmt.Sprintf("dev: %s, cmd: %s, mod: %s", devname, cmdname, module.Config.Name)
ierr.Errs[m] = err
}
}
}
}

if len(ierr.Errs) != 0 {
return ierr
}

log.Print("Module Initialization OK")

return nil
}
9 changes: 6 additions & 3 deletions pkg/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ type Module interface {
// Help returns a formatted string with the capabilities of the module.
// It provides any user information required to interact with the module.
Help() string
// Init is called when the module is loaded by dutagent on an execution request for a command that uses this module.
// Init is called once when the dutagent services is started.
// It's a good place to establish connections or allocate resources and check whether
// the module is configured functional
Init() error
// Deinit is called when the module is unloaded by dutagent after the execution of a command that uses this module.
// It is used to clean up any resources that were allocated during the Init phase.
// Deinit is called when the module is unloaded by dutagent or an internal error occurs.
// It is used to clean up any resources that were allocated during the Init phase and
// shall guarantee a graceful shutdown of the service
Deinit() error
// Run is the entry point and executes the module with the given arguments.
Run(ctx context.Context, s Session, args ...string) error
Expand Down

0 comments on commit c34757f

Please sign in to comment.