diff --git a/.github/workflows/validation.yaml b/.github/workflows/validation.yaml index 632ed95..ec1b2d6 100644 --- a/.github/workflows/validation.yaml +++ b/.github/workflows/validation.yaml @@ -7,14 +7,20 @@ on: - "main" paths: - vehicle-simulator/**/*.go + - custom-update-agent/**/*.go - .github/**/*.yaml pull_request: paths: - vehicle-simulator/**/*.go + - custom-update-agent/**/*.go - .github/**/*.yaml jobs: - call-go-validation: + call-go-validation-vs: uses: eclipse-kanto/example-applications/.github/workflows/go-validation.yaml@main with: - work-dir-path: ./vehicle-simulator \ No newline at end of file + work-dir-path: ./vehicle-simulator + call-go-validation-cua: + uses: eclipse-kanto/example-applications/.github/workflows/go-validation.yaml@main + with: + work-dir-path: ./custom-update-agent \ No newline at end of file diff --git a/custom-update-agent/README.md b/custom-update-agent/README.md index bdf54f5..e8bf93b 100644 --- a/custom-update-agent/README.md +++ b/custom-update-agent/README.md @@ -54,8 +54,7 @@ You must have an installed and working instance of: * Eclipse Kanto Update Manager * Eclipse Kanto Container Management - -Regardless if you are running the update agent as a standard or containerized application, you will need to add the following to the update manager configuration, located at `/etc/update-manager/config.json`: +Regardless if you are running the update agent as a standard or containerized application, you will need to add the following to the update manager configuration, located at `/etc/kanto-update-manager/config.json`: ```json { diff --git a/custom-update-agent/main.go b/custom-update-agent/main.go index 73788c6..f887ae3 100644 --- a/custom-update-agent/main.go +++ b/custom-update-agent/main.go @@ -31,23 +31,24 @@ func main() { logger := util.ConfigLogger(slog.LevelDebug, os.Stdout) slog.SetDefault(&logger) - fileDirPtr := flag.String("dir", "./fileagent", "the path to the directory where file agent will manage files") + flag.StringVar(&updateagent.FileDirectory, "dir", "./fileagent", "the path to the directory where file agent will manage files") flag.Parse() - updateagent.FileDirectory = *fileDirPtr - updateAgent, _ := updateagent.Init(*mqtt.NewDefaultConfig(), "files") - err := updateAgent.(api.UpdateAgent).Start(context.Background()) + updateAgent, err := updateagent.Init(mqtt.NewDefaultConfig(), "files") if err != nil { + slog.Error("could not initialize an Update Agent service! got", "error", err) + os.Exit(1) + } + if err := updateAgent.(api.UpdateAgent).Start(context.Background()); err != nil { slog.Error("could not start Update Agent service! got", "error", err) - } else { - slog.Info("successfully started Update Agent service") + os.Exit(2) } + slog.Info("successfully started Update Agent service") var signalChan = make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGHUP) sig := <-signalChan - slog.Info("Exiting!, recieved", "signal", sig) + slog.Info("Exiting!, received", "signal", sig) updateAgent.(api.UpdateAgent).Stop() - } diff --git a/custom-update-agent/updateagent/update_agent_init.go b/custom-update-agent/updateagent/update_agent_init.go index bcfc2e8..57e2809 100644 --- a/custom-update-agent/updateagent/update_agent_init.go +++ b/custom-update-agent/updateagent/update_agent_init.go @@ -18,56 +18,19 @@ import ( "github.com/eclipse-kanto/update-manager/mqtt" ) -func newUpdateAgent( - domainName string, - broker string, - keepAlive string, - disconnectTimeout string, - clientUsername string, - clientPassword string, - connectTimeout string, - acknowledgeTimeout string, - subscribeTimeout string, - unsubscribeTimeout string, -) (api.UpdateAgent, error) { - - mqttClient, _ := mqtt.NewUpdateAgentClient(domainName, &mqtt.ConnectionConfig{ - Broker: broker, - KeepAlive: keepAlive, - DisconnectTimeout: disconnectTimeout, - Username: clientUsername, - Password: clientPassword, - ConnectTimeout: connectTimeout, - AcknowledgeTimeout: acknowledgeTimeout, - SubscribeTimeout: subscribeTimeout, - UnsubscribeTimeout: unsubscribeTimeout, - }) - - return agent.NewUpdateAgent(mqttClient, newUpdateManager(domainName)), nil -} - // newUpdateManager instantiates a new update manager instance func newUpdateManager(domainName string) api.UpdateManager { return &fileUpdateManager{ - domainName: domainName, - + domainName: domainName, createUpdateOperation: newOperation, } } // Init initializes a new Update Agent instance using given configuration and domain -func Init(config mqtt.ConnectionConfig, domain string) (interface{}, error) { - - return newUpdateAgent( - domain, - config.Broker, - config.KeepAlive, - config.DisconnectTimeout, - config.Username, - config.Password, - config.ConnectTimeout, - config.AcknowledgeTimeout, - config.SubscribeTimeout, - config.UnsubscribeTimeout, - ) +func Init(config *mqtt.ConnectionConfig, domainName string) (interface{}, error) { + mqttClient, err := mqtt.NewUpdateAgentClient(domainName, config) + if err != nil { + return nil, err + } + return agent.NewUpdateAgent(mqttClient, newUpdateManager(domainName)), nil } diff --git a/custom-update-agent/updateagent/update_manager.go b/custom-update-agent/updateagent/update_manager.go index a8cc2b2..9bd3987 100644 --- a/custom-update-agent/updateagent/update_manager.go +++ b/custom-update-agent/updateagent/update_manager.go @@ -49,7 +49,6 @@ type fileUpdateManager struct { // Name returns the name of this update manager, e.g. "files". func (updMgr *fileUpdateManager) Name() string { - return updMgr.domainName } @@ -165,12 +164,10 @@ func (updMgr *fileUpdateManager) getCurrentFiles() []*types.SoftwareNode { if err != nil { slog.Error("got error checking current files", "error", err) return nil - } _, err = os.Create(propsFilePath) if err != nil { slog.Error(fmt.Sprintf("got error creating file [%s]", "state.props"), "error", err) - } for _, entry := range entries { addProperty(entry.Name(), "unknown") @@ -180,15 +177,12 @@ func (updMgr *fileUpdateManager) getCurrentFiles() []*types.SoftwareNode { if err != nil { slog.Error("got error checking current files", "error", err) return nil - } properties, err := props.Read(propsFile) if err != nil { - slog.Error("got error when reading state.props file", "error", err) return nil - } for _, filename := range properties.Names() { @@ -206,7 +200,7 @@ func (updMgr *fileUpdateManager) Dispose() error { // WatchEvents subscribes for events that update the current state inventory func (updMgr *fileUpdateManager) WatchEvents(ctx context.Context) { - // no container events handled yet - current state inventory reported only on initial start or explicit get request + // no events handled yet - current state inventory reported only on initial start or explicit get request } // SetCallback sets the callback instance that is used for desired state feedback / current state notifications. diff --git a/custom-update-agent/updateagent/update_operation.go b/custom-update-agent/updateagent/update_operation.go index dda045a..a7ff805 100644 --- a/custom-update-agent/updateagent/update_operation.go +++ b/custom-update-agent/updateagent/update_operation.go @@ -110,14 +110,12 @@ func (o *operation) Identify() (bool, error) { if err != nil { slog.Error("got error opening state.props file", "error", err) return false, err - } properties, err := props.Read(propsFile) if err != nil { slog.Error("got error reading state.props file", "error", err) return false, err - } for _, filename := range properties.Names() { @@ -176,9 +174,7 @@ func (o *operation) newRemoveActions(toBeRemoved map[string]*util.File) []*fileA removeActions := []*fileAction{} message := util.GetActionMessage(util.ActionRemove) for _, current := range toBeRemoved { - slog.Debug(fmt.Sprintf("[%s] %s", current.Name, message)) - removeActions = append(removeActions, &fileAction{ desired: nil, current: current, @@ -199,10 +195,8 @@ func (o *operation) newRemoveActions(toBeRemoved map[string]*util.File) []*fileA func (o *operation) Execute(command types.CommandType, baseline string) { commandHandler, action := o.getCommandHandler(baseline, command) if action == nil { - return } - commandHandler(o, action) } @@ -330,18 +324,13 @@ func activate(o *operation, baselineAction *action) { lastAction = action if action.actionType == util.ActionAdd || action.actionType == util.ActionReplace || action.actionType == util.ActionNone { - o.updateBaselineActionStatus(baselineAction, types.BaselineStatusActivating, action, types.ActionStatusActivating, action.feedbackAction.Message) lastActionMessage = "Desired file added to state.props file." - - err := addProperty(action.desired.Name, action.desired.DownloadURL) - - if err != nil { + if err := addProperty(action.desired.Name, action.desired.DownloadURL); err != nil { lastActionErr = err slog.Error("got error updating state.props file", "error", err) return } - } else { lastAction = nil } @@ -370,7 +359,6 @@ func update(o *operation, baselineAction *action) { actions := baselineAction.actions for _, action := range actions { - if lastAction != nil { lastAction.feedbackAction.Status = types.ActionStatusUpdateSuccess lastAction.feedbackAction.Message = lastActionMessage @@ -384,15 +372,11 @@ func update(o *operation, baselineAction *action) { } lastActionMessage = "File added to directory." } else if action.actionType == util.ActionRemove { - err := o.removeFile(action.current) - - if err != nil { + if err := o.removeFile(action.current); err != nil { lastActionErr = err return - } lastActionMessage = "File removed from directory." - } else { lastActionMessage = action.feedbackAction.Message } @@ -496,7 +480,6 @@ func (o *operation) copyFile(filename string, sourcePath string, destinationPath if err != nil { slog.Error(fmt.Sprintf("got error opening file [%s]", filename), "error", err) return err - } defer sourceFile.Close() destinationFile, err := os.Create(destinationPath + "/" + filename) @@ -531,7 +514,6 @@ func (o *operation) removeFile(desired *util.File) error { } func (o *operation) downloadFile(desired *util.File) error { - resp, err := http.Get(desired.DownloadURL) if err != nil { slog.Debug(fmt.Sprintf("could not download file from url [%s]", desired.DownloadURL), "error", err) @@ -543,7 +525,6 @@ func (o *operation) downloadFile(desired *util.File) error { if err != nil { slog.Debug(fmt.Sprintf("could not create file [%s]", desired.Name), "error", err) return err - } defer out.Close() diff --git a/custom-update-agent/util/to_files.go b/custom-update-agent/util/to_files.go index 4fcfbd8..a054693 100644 --- a/custom-update-agent/util/to_files.go +++ b/custom-update-agent/util/to_files.go @@ -31,10 +31,14 @@ func ToFiles(components []*types.ComponentWithConfig) ([]*File, error) { } func toFile(component *types.ComponentWithConfig) (*File, error) { - file := &File{ - Name: component.Config[0].Value, - DownloadURL: component.Config[1].Value, + file := &File{} + for _, kvPair := range component.Config { + if kvPair.Key == "file_name" { + file.Name = kvPair.Value + } + if kvPair.Key == "download_url" { + file.DownloadURL = kvPair.Value + } } - return file, nil }